diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml new file mode 100644 index 00000000..2fd4d7b2 --- /dev/null +++ b/.github/workflows/create-release.yml @@ -0,0 +1,104 @@ +name: Create Release on PR Merge + +on: + pull_request: + types: + - closed + branches: + - master # Change to your default branch if different (e.g., master) + workflow_dispatch: + +jobs: + create_release: + # Only run when PR is merged (not when just closed) + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + permissions: + contents: write # Needed for creating releases + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 # Fetch all history for proper versioning and commit messages + + - name: Get latest release version + id: get_version + run: | + # Get latest tag or set to v0.0.0 if none exists + LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") + echo "LATEST_TAG=${LATEST_TAG}" >> $GITHUB_ENV + + # Extract version numbers + MAJOR=$(echo $LATEST_TAG | sed 's/v\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/') + MINOR=$(echo $LATEST_TAG | sed 's/v\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/') + PATCH=$(echo $LATEST_TAG | sed 's/v\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/') + + # Check PR labels to determine which version to increment + if [[ "${{ contains(github.event.pull_request.labels.*.name, 'major') }}" == "true" ]]; then + echo "Incrementing MAJOR version due to 'major' label" + MAJOR=$((MAJOR + 1)) + MINOR=0 + PATCH=0 + elif [[ "${{ contains(github.event.pull_request.labels.*.name, 'minor') }}" == "true" ]]; then + echo "Incrementing MINOR version due to 'minor' label" + MINOR=$((MINOR + 1)) + PATCH=0 + else + echo "Incrementing PATCH version (default)" + PATCH=$((PATCH + 1)) + fi + + NEW_TAG="v$MAJOR.$MINOR.$PATCH" + echo "Bumping version from $LATEST_TAG to $NEW_TAG" + echo "NEW_TAG=${NEW_TAG}" >> $GITHUB_ENV + + - name: Generate Release Notes + id: release_notes + run: | + # Get commits since last tag + echo "Generating commit list since $LATEST_TAG" + COMMITS=$(git log --pretty=format:"- %s (%h)" ${{ env.LATEST_TAG }}..HEAD) + + # Extract PR details + PR_TITLE="${{ github.event.pull_request.title }}" + PR_NUMBER="${{ github.event.pull_request.number }}" + PR_BODY="${{ github.event.pull_request.body }}" + PR_USER="${{ github.event.pull_request.merged_by.login }}" + + # Save release notes to environment variable + echo "RELEASE_NOTES<> $GITHUB_ENV + echo "## Release ${{ env.NEW_TAG }}" >> $GITHUB_ENV + echo "" >> $GITHUB_ENV + echo "### 🔄 Pull Request" >> $GITHUB_ENV + echo "- #$PR_NUMBER: $PR_TITLE" >> $GITHUB_ENV + echo "- Merged by @$PR_USER" >> $GITHUB_ENV + echo "" >> $GITHUB_ENV + + if [[ -n "$PR_BODY" ]]; then + echo "### 📠Description" >> $GITHUB_ENV + echo "$PR_BODY" >> $GITHUB_ENV + echo "" >> $GITHUB_ENV + fi + + echo "### 📦 Changes" >> $GITHUB_ENV + echo "$COMMITS" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ env.NEW_TAG }} + name: Release ${{ env.NEW_TAG }} + body: ${{ env.RELEASE_NOTES }} + draft: false # Set to true if you want to review before publishing + prerelease: false # Set to true for pre-releases + # If you have build artifacts to include, uncomment and modify this: + # files: | + # dist/*.zip + # dist/*.tar.gz + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Output Results + run: | + echo "::notice::🎉 Created release ${{ env.NEW_TAG }} from PR #${{ github.event.pull_request.number }}" \ No newline at end of file diff --git a/.github/workflows/createpypirelease.yml b/.github/workflows/createpypirelease.yml new file mode 100644 index 00000000..646e956a --- /dev/null +++ b/.github/workflows/createpypirelease.yml @@ -0,0 +1,41 @@ +"name: Publish Python ðŸ distributions 📦 to PyPI and TestPyPI + +on: push + +jobs: + build-n-publish: + name: Build and publish Python ðŸ distributions 📦 to PyPI and TestPyPI + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Set up Python 3.9 + uses: actions/setup-python@v1 + with: + python-version: 3.9 + - name: Install pypa/build + run: >- + python -m + pip install + build + --user + - name: Build a binary wheel and a source tarball + run: >- + python -m + build + --sdist + --wheel + --outdir dist/ + . + - name: Publish distribution 📦 to Test PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + password: ${{ secrets.TEST_PYPI_API_TOKEN }} + repository_url: https://test.pypi.org/legacy/ + skip_existing: true + - name: Publish distribution 📦 to PyPI + if: startsWith(github.ref, 'refs/tags') + uses: pypa/gh-action-pypi-publish@release/v1 + with: + password: ${{ secrets.PYPI_API_TOKEN }}" + +#Não funciona pq não tenho secret keys \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..a6b35177 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,38 @@ +name: Deploy to GitHub Pages + +on: + push: + branches: + - core-seperation # ou master, dependendo da sua branch principal + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '18' + + - name: Install dependencies + run: | + cd docs-site + npm ci + + - name: Build + run: | + cd docs-site + npm run build + + - name: Create .nojekyll file + run: | + touch docs-site/out/.nojekyll + + - name: Deploy + uses: JamesIves/github-pages-deploy-action@v4 + with: + folder: docs-site/out + branch: gh-pages \ No newline at end of file diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 00000000..0eafe4d4 --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,26 @@ +name: Format + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Install uv + run: pip install uv + - name: Create virtual environment + run: uv venv + - name: Install dependencies + run: uv pip install -e ".[dev]" + - name: format + run: uv run black . \ No newline at end of file diff --git a/.github/workflows/install.yml b/.github/workflows/install.yml new file mode 100644 index 00000000..d43be627 --- /dev/null +++ b/.github/workflows/install.yml @@ -0,0 +1,23 @@ +name: Install +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Install uv + run: pip install uv + - name: Create virtual environment + run: uv venv + - name: Install package + run: uv pip install -e . \ No newline at end of file diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..5ad024c6 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,28 @@ +name: Lint +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Install uv + run: pip install uv + - name: Create virtual environment + run: uv venv + - name: Install dependencies + run: uv pip install -e ".[dev]" + - name: lint + run: | + uv run ruff check --fix . + uv run ruff check . + uv run flake8 yake/ \ No newline at end of file diff --git a/.github/workflows/publishpypi.yml b/.github/workflows/publishpypi.yml new file mode 100644 index 00000000..ffc099d6 --- /dev/null +++ b/.github/workflows/publishpypi.yml @@ -0,0 +1,42 @@ +"name: Publish Python ðŸ distributions 📦 to PyPI and TestPyPI + +on: push + +jobs: + build-n-publish: + name: Build and publish Python ðŸ distributions 📦 to PyPI and TestPyPI + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Set up Python 3.9 + uses: actions/setup-python@v1 + with: + python-version: 3.9 + - name: Install pypa/build + run: >- + python -m + pip install + build + --user + - name: Build a binary wheel and a source tarball + run: >- + python -m + build + --sdist + --wheel + --outdir dist/ + . + - name: Publish distribution 📦 to Test PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + password: ${{ secrets.TEST_PYPI_API_TOKEN }} + repository_url: https://test.pypi.org/legacy/ + skip_existing: true + - name: Publish distribution 📦 to PyPI + if: startsWith(github.ref, 'refs/tags') + uses: pypa/gh-action-pypi-publish@release/v1 + with: + password: ${{ secrets.PYPI_API_TOKEN }} +" + +#não está a funcionar pq não tenho as secret keys \ No newline at end of file diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml new file mode 100644 index 00000000..c73e032c --- /dev/null +++ b/.github/workflows/pylint.yml @@ -0,0 +1,23 @@ +name: Pylint + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.8", "3.9", "3.10"] + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pylint + - name: Analysing the code with pylint + run: | + pylint $(git ls-files '*.py') diff --git a/.github/workflows/resultados.yml b/.github/workflows/resultados.yml new file mode 100644 index 00000000..a118e005 --- /dev/null +++ b/.github/workflows/resultados.yml @@ -0,0 +1,56 @@ +name: Run YAKE Tests + +on: + push: + branches: + - master + pull_request: + branches: + - master + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + + - name: Install uv + run: pip install uv + + - name: Create virtual environment + run: uv venv + + - name: Install dependencies + run: | + uv pip install -e ".[dev]" + uv pip install pytest + + - name: Run tests + id: run-tests + run: | + uv run pytest -v tests/test_yake.py | tee test_output.log + + - name: Verify test results + run: | + if grep -q '6 passed' test_output.log; then + echo "✅ Todos os testes passaram com sucesso!" + exit 0 + else + echo "⌠Alguns testes falharam! Verifique o log para mais detalhes." + exit 1 + fi + + - name: Upload test results (em caso de falha) + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-logs + path: test_output.log \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..e79c6fd1 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,25 @@ +name: Test +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Install uv + run: pip install uv + - name: Create virtual environment + run: uv venv + - name: Install dependencies + run: uv pip install -e ".[dev]" + - name: test + run: uv run pytest -vv --cov=yake tests/ \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..21c8b059 --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# Dependency directories +node_modules/ +.npm +# Don't ignore these files +!.next/ +!out/ + +# Python +__pycache__/ +*.py[cod] +*.pyo +*.pyd +*.so + +# Virtual environments +.venv/ +venv/ +ENV/ +env/ +*.env + +# Hatch/uv/pytest +.uv/ +.uv.lock +.pytest_cache/ +.coverage +htmlcov/ +.cache/ +dist/ +build/ +*.egg-info/ + +# VSCode +.vscode/ + +# Logs +*.log + +# OS files +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/.python-version b/.python-version new file mode 100644 index 00000000..c8cfe395 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.10 diff --git a/AUTHORS.rst b/AUTHORS.rst deleted file mode 100644 index 3dda713c..00000000 --- a/AUTHORS.rst +++ /dev/null @@ -1,21 +0,0 @@ -======= -Credits -======= - -Development ----------------- - -* Ricardo Campos -* Vitor Mangaravite -* Arian Pasquali -* Alípio Jorge - -Contributors ------------- - -None yet. Why not be the first? - - -DevOps - Docker ----------------- -* João Rocha da Silva diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 021f78aa..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,11 +0,0 @@ -include AUTHORS.rst -include CONTRIBUTING.rst -include LICENSE -include README.rst - -recursive-include tests * -recursive-exclude * __pycache__ -recursive-exclude * *.py[co] - -recursive-include yake/StopwordsList *.txt -recursive-include docs *.rst conf.py Makefile make.bat *.jpg *.png *.gif diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..03b45367 --- /dev/null +++ b/Makefile @@ -0,0 +1,36 @@ +install: + uv pip install --upgrade pip + uv pip install -e . + +install-dev: + uv pip install --upgrade pip + uv pip install -e ".[dev]" + +test: + uv run pytest -vv --cov=yake test_*.py + +format: + uv run black . + +lint: + uv run ruff check --fix . + uv run ruff check . + uv run flake8 yake/ + +clean: + rm -rf build/ + rm -rf dist/ + rm -rf *.egg-info/ + find . -type d -name __pycache__ -delete + find . -type f -name "*.pyc" -delete + +build: + uv build + +deploy: + uv build + uv publish + +all: install-dev lint test format + +.PHONY: install install-dev test format lint clean build deploy all \ No newline at end of file diff --git a/README.md b/README.md index ceccb29d..acd27348 100644 --- a/README.md +++ b/README.md @@ -1,166 +1,79 @@ -# Yet Another Keyword Extractor (Yake) +# YAKE! (Yet Another Keyword Extractor) -Unsupervised Approach for Automatic Keyword Extraction using Text Features. +[![ECIR'18 Best Short Paper](https://img.shields.io/badge/ECIR'18-Best%20Short%20Paper-brightgreen.svg)](http://ecir2018.org) [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/tiagolv/yakerf/blob/gh-pages/1YAKE.ipynb) -YAKE! is a light-weight unsupervised automatic keyword extraction method which rests on text statistical features extracted from single documents to select the most important keywords of a text. Our system does not need to be trained on a particular set of documents, neither it depends on dictionaries, external-corpus, size of the text, language or domain. To demonstrate the merits and the significance of our proposal, we compare it against ten state-of-the-art unsupervised approaches (TF.IDF, KP-Miner, RAKE, TextRank, SingleRank, ExpandRank, TopicRank, TopicalPageRank, PositionRank and MultipartiteRank), and one supervised method (KEA). Experimental results carried out on top of twenty datasets (see Benchmark section below) show that our methods significantly outperform state-of-the-art methods under a number of collections of different sizes, languages or domains. In addition to the python package here described, we also make available a demo, an API and a mobile app. +YAKE! is a lightweight unsupervised automatic keyword extraction method that uses text statistical features to select the most important keywords from a document. It requires no training, external corpus, or dictionaries, and works across multiple languages and domains regardless of text size. -## Main Features +## Features -* Unsupervised approach -* Corpus-Independent -* Domain and Language Independent -* Single-Document +- 🚀 Unsupervised approach +- 🌠Language and domain independent +- 📄 Single-document focused +- 🧠 No training or dictionaries required -## Benchmark - -For Benchmark results check out our paper published on Information Science Journal (see the references section). - -## Rationale - -Extracting keywords from texts has become a challenge for individuals and organizations as the information grows in complexity and size. The need to automate this task so that texts can be processed in a timely and adequate manner has led to the emergence of automatic keyword extraction tools. Despite the advances, there is a clear lack of multilingual online tools to automatically extract keywords from single documents. Yake! is a novel feature-based system for multi-lingual keyword extraction, which supports texts of different sizes, domain or languages. Unlike other approaches, Yake! does not rely on dictionaries nor thesauri, neither is trained against any corpora. Instead, it follows an unsupervised approach which builds upon features extracted from the text, making it thus applicable to documents written in different languages without the need for further knowledge. This can be beneficial for a large number of tasks and a plethora of situations where the access to training corpora is either limited or restricted. - -## Where can I find YAKE!? -YAKE! is available online [http://yake.inesctec.pt], on [Google Play](https://play.google.com/store/apps/details?id=com.yake.yake), as an open source Python package [https://github.com/LIAAD/yake] and as an [API](http://yake.inesctec.pt/apidocs/#/available_methods/post_yake_v2_extract_keywords). - -## Installing YAKE! - -There are three installation alternatives. - -- To run YAKE! in the command line (say, to integrate in a script), but you do not need an HTTP server on top, you can use our [simple YAKE! Docker image](#cli-image). This container will allow you to run text extraction as a command, and then exit. -- To run YAKE! as an HTTP server featuring a RESTful API (say to integrate in a web application or host your own YAKE!), you can use our [RESTful API server image](#rest-api-image). This container/server *will run in the background*. -- To install YAKE! straight "on the metal" or you want to integrate it in your Python app, you can [install it and its dependencies](#standalone-installation). - - -### Option 1. YAKE as a CLI utility inside a Docker container - -First, install Docker. Ubuntu users, please see our [script below](#installing-docker) for a complete installation script. - -Then, run: +## Quick Installation ```bash -docker run liaad/yake:latest -ti "Caffeine is a central nervous system (CNS) stimulant of the methylxanthine class.[10] It is the world's most widely consumed psychoactive drug. Unlike many other psychoactive substances, it is legal and unregulated in nearly all parts of the world. There are several known mechanisms of action to explain the effects of caffeine. The most prominent is that it reversibly blocks the action of adenosine on its receptor and consequently prevents the onset of drowsiness induced by adenosine. Caffeine also stimulates certain portions of the autonomic nervous system." +uv pip install git+https://github.com/LIAAD/yake ``` -*Example text from Wikipedia* - -### Option 2. REST API Server in a Docker container - -This install will provide you a mirror of the original REST API of YAKE! available [here](https://boiling-castle-88317.herokuapp.com). +or ```bash -docker run -p 5000:5000 -d liaad/yake-server:latest -``` - -After it starts up, the container will run in the background, at http://127.0.0.1:5000. To access the YAKE! API documentation, go to http://127.0.0.1:5000/apidocs/. - -You can test the RESTful API using `curl`: - -```bash -curl -X POST "http://localhost:5000/yake/" -H "accept: application/json" -H "Content-Type: application/json" \ --d @- <<'EOF' -{ - "language": "en", - "max_ngram_size": 3, - "number_of_keywords": 10, - "text": "Sources tell us that Google is acquiring Kaggle, a platform that hosts data science and machine learning competitions. Details about the transaction remain somewhat vague , but given that Google is hosting its Cloud Next conference in San Francisco this week, the official announcement could come as early as tomorrow. Reached by phone, Kaggle co-founder CEO Anthony Goldbloom declined to deny that the acquisition is happening. Google itself declined 'to comment on rumors'. Kaggle, which has about half a million data scientists on its platform, was founded by Goldbloom and Ben Hamner in 2010. The service got an early start and even though it has a few competitors like DrivenData, TopCoder and HackerRank, it has managed to stay well ahead of them by focusing on its specific niche. The service is basically the de facto home for running data science and machine learning competitions. With Kaggle, Google is buying one of the largest and most active communities for data scientists ..." -} -EOF -``` -*Example text from Wikipedia* - - -### Option 3. Standalone Installation (for development or integration) - -#### Requirements - -Python3 - -#### Installation - -To install Yake using pip: - -``` bash -pip install git+https://github.com/LIAAD/yake +uv pip install yake ``` -To upgrade using pip: +## Basic Usage -``` bash -pip install git+https://github.com/LIAAD/yake –-upgrade -``` #### Usage (Command line) How to use it on your favorite command line + ``` bash Usage: yake [OPTIONS] Options: - -ti, --text_input TEXT Input text, SURROUNDED by single quotes(') - -i, --input_file TEXT Input file - -l, --language TEXT Language - -n, --ngram-size INTEGER Max size of the ngram. - -df, --dedup-func [leve|jaro|seqm] - Deduplication function. - -dl, --dedup-lim FLOAT Deduplication limiar. - -ws, --window-size INTEGER Window size. - -t, --top INTEGER Number of keyphrases to extract - -v, --verbose Gets detailed information (such as the score) - --help Show this message and exit. -``` -### Usage (Python) - -How to use it on Python - -``` python + -ti, --text_input TEXT Input text, SURROUNDED by single quotes (') + -i, --input_file TEXT Input file + -l, --language TEXT Language + -n, --ngram-size INTEGER Max size of the ngram. + -df, --dedup-func [leve|jaro|seqm] * + Deduplication function. + -dl, --dedup-lim FLOAT Deduplication limiar. + -ws, --window-size INTEGER Window size. + -t, --top INTEGER Number of keyphrases to extract + -v, --verbose Gets detailed information (such as the score) + --help Show this message and exit. +``` + +Dont know which Deduplication function to use, see more [here](https://tiagolv.github.io/yakerf/docs/-getting-started#keyword-deduplication-methods) + +#### Usage (Python) + +```python import yake -text = "Sources tell us that Google is acquiring Kaggle, a platform that hosts data science and machine learning "\ -"competitions. Details about the transaction remain somewhat vague, but given that Google is hosting its Cloud "\ -"Next conference in San Francisco this week, the official announcement could come as early as tomorrow. "\ -"Reached by phone, Kaggle co-founder CEO Anthony Goldbloom declined to deny that the acquisition is happening. "\ -"Google itself declined 'to comment on rumors'. Kaggle, which has about half a million data scientists on its platform, "\ -"was founded by Goldbloom and Ben Hamner in 2010. "\ -"The service got an early start and even though it has a few competitors like DrivenData, TopCoder and HackerRank, "\ -"it has managed to stay well ahead of them by focusing on its specific niche. "\ -"The service is basically the de facto home for running data science and machine learning competitions. "\ -"With Kaggle, Google is buying one of the largest and most active communities for data scientists - and with that, "\ -"it will get increased mindshare in this community, too (though it already has plenty of that thanks to Tensorflow "\ -"and other projects). Kaggle has a bit of a history with Google, too, but that's pretty recent. Earlier this month, "\ -"Google and Kaggle teamed up to host a $100,000 machine learning competition around classifying YouTube videos. "\ -"That competition had some deep integrations with the Google Cloud Platform, too. Our understanding is that Google "\ -"will keep the service running - likely under its current name. While the acquisition is probably more about "\ -"Kaggle's community than technology, Kaggle did build some interesting tools for hosting its competition "\ -"and 'kernels', too. On Kaggle, kernels are basically the source code for analyzing data sets and developers can "\ -"share this code on the platform (the company previously called them 'scripts'). "\ -"Like similar competition-centric sites, Kaggle also runs a job board, too. It's unclear what Google will do with "\ -"that part of the service. According to Crunchbase, Kaggle raised $12.5 million (though PitchBook says it's $12.75) "\ -"since its launch in 2010. Investors in Kaggle include Index Ventures, SV Angel, Max Levchin, Naval Ravikant, "\ -"Google chief economist Hal Varian, Khosla Ventures and Yuri Milner " -``` +text = "Sources tell us that Google is acquiring Kaggle, a platform that hosts data science and machine learning competitions. Details about the transaction remain somewhat vague, but given that Google is hosting its Cloud Next conference in San Francisco this week, the official announcement could come as early as tomorrow. Reached by phone, Kaggle co-founder CEO Anthony Goldbloom declined to deny that the acquisition is happening. Google itself declined 'to comment on rumors'. Kaggle, which has about half a million data scientists on its platform, was founded by Goldbloom and Ben Hamner in 2010. The service got an early start and even though it has a few competitors like DrivenData, TopCoder and HackerRank, it has managed to stay well ahead of them by focusing on its specific niche. The service is basically the de facto home for running data science and machine learning competitions. With Kaggle, Google is buying one of the largest and most active communities for data scientists - and with that, it will get increased mindshare in this community, too (though it already has plenty of that thanks to Tensorflow and other projects). Kaggle has a bit of a history with Google, too, but that's pretty recent. Earlier this month, Google and Kaggle teamed up to host a $100,000 machine learning competition around classifying YouTube videos. That competition had some deep integrations with the Google Cloud Platform, too. Our understanding is that Google will keep the service running - likely under its current name. While the acquisition is probably more about Kaggle's community than technology, Kaggle did build some interesting tools for hosting its competition and 'kernels', too. On Kaggle, kernels are basically the source code for analyzing data sets and developers can share this code on the platform (the company previously called them 'scripts'). Like similar competition-centric sites, Kaggle also runs a job board, too. It's unclear what Google will do with that part of the service. According to Crunchbase, Kaggle raised $12.5 million (though PitchBook says it's $12.75) since its launch in 2010. Investors in Kaggle include Index Ventures, SV Angel, Max Levchin, Naval Ravikant, Google chief economist Hal Varian, Khosla Ventures and Yuri Milner " -#### assuming default parameters -```bash +# Simple usage with default parameters kw_extractor = yake.KeywordExtractor() keywords = kw_extractor.extract_keywords(text) -for kw in keywords: - print(kw) -``` +for kw, score in keywords: + print(f"{kw} ({score})") -#### specifying parameters -```bash -language = "en" -max_ngram_size = 3 -deduplication_threshold = 0.9 -deduplication_algo = 'seqm' -windowSize = 1 -numOfKeywords = 20 - -custom_kw_extractor = yake.KeywordExtractor(lan=language, n=max_ngram_size, dedupLim=deduplication_threshold, dedupFunc=deduplication_algo, windowsSize=windowSize, top=numOfKeywords, features=None) -keywords = custom_kw_extractor.extract_keywords(text) +# With custom parameters +custom_kw_extractor = yake.KeywordExtractor( + lan="en", # language + n=3, # ngram size + dedupLim=0.9, # deduplication threshold + dedupFunc='seqm', # deduplication function + windowsSize=1, # context window + top=10, # number of keywords to extract + features=None # custom features +) -for kw in keywords: - print(kw) +keywords = custom_kw_extractor.extract_keywords(text) ``` #### Output @@ -174,185 +87,59 @@ The lower the score, the more relevant the keyword is. ('google cloud platform', 0.06261974476422487) ('co-founder ceo anthony', 0.07357749587020043) ('acquiring kaggle', 0.08723571551039863) -('ceo anthony', 0.08915156857226395) -('anthony goldbloom', 0.09123482372372106) -('machine learning', 0.09147989238151344) -('kaggle co-founder ceo', 0.093805063905847) -('data', 0.097574333771058) -('google cloud', 0.10260128641464673) -('machine learning competitions', 0.10773000650607861) -('francisco this week', 0.11519915079240485) -('platform', 0.1183512305596321) -('conference in san', 0.12392066376108138) -('service', 0.12546743261462942) -('goldbloom', 0.14611408778815776) ``` -### Highlighting Feature -Highlighting feature will tag every keyword in the text with the default tag ``. -``` python - -from yake.highlight import TextHighlighter - -th = TextHighlighter(max_ngram_size = 3) -th.highlight(text, keywords) - -``` -#### Output -By default, keywords will be highlighted using the tag 'kw'. -``` -Sources tell us that google is acquiring kaggle, a platform that hosts data science and machine learning competitions. Details about the transaction remain somewhat vague , but given that google is hosting its Cloud Next conference in san francisco this week, the official announcement could come as early as tomorrow. Reached by phone, Kaggle co-founder ceo anthony goldbloom declined to deny that the acquisition is happening. google itself declined 'to comment on rumors'. -..... -..... -``` +## Multilingual Support -### Custom Highlighting Feature -Besides tagging a text with the default tag, users can also specify their own custom highlight. In the following text, the tag `` makes use of an hyphotetical function `my_class` whose purpose would be to highlight in white colour or the relevant keywords. +YAKE! supports multiple languages. Example with Portuguese text: -#### Output ```python - -from yake.highlight import TextHighlighter -th = TextHighlighter(max_ngram_size = 3, highlight_pre = "", highlight_post= "") -th.highlight(text, keywords) -``` - -``` -self.highlight_postSources tell us that google is acquiring kaggle, a platform that hosts data science and machine learning self.highlight_postcompetitions. Details about the transaction remain somewhat vague , but given that google is hosting self.highlight_postits Cloud Next conference in san francisco this week, the official announcement could come as early self.highlight_postas tomorrow. Reached by phone, Kaggle co-founder ceo anthony goldbloom declined to deny that the self.highlight_postacquisition is happening. google itself declined 'to comment on rumors'. -..... -..... -``` - -### Languages others than English -While English (`en`) is the default language, users can use YAKE! to extract keywords from whatever language they want to by specifying the the corresponding language universal code. The below example shows how to extract keywords from a portuguese text. -``` bash -text = ''' -"Conta-me Histórias." Xutos inspiram projeto premiado. A plataforma "Conta-me Histórias" foi distinguida com o Prémio Arquivo.pt, atribuído a trabalhos inovadores de investigação ou aplicação de recursos preservados da Web, através dos serviços de pesquisa e acesso disponibilizados publicamente pelo Arquivo.pt . Nesta plataforma em desenvolvimento, o utilizador pode pesquisar sobre qualquer tema e ainda executar alguns exemplos predefinidos. Como forma de garantir a pluralidade e diversidade de fontes de informação, esta são utilizadas 24 fontes de notícias eletrónicas, incluindo a TSF. Uma versão experimental (beta) do "Conta-me Histórias" está disponível aqui. -A plataforma foi desenvolvida por Ricardo Campos investigador do LIAAD do INESC TEC e docente do Instituto Politécnico de Tomar, Arian Pasquali e Vitor Mangaravite, também investigadores do LIAAD do INESC TEC, Alípio Jorge, coordenador do LIAAD do INESC TEC e docente na Faculdade de Ciências da Universidade do Porto, e Adam Jatwot docente da Universidade de Kyoto. -''' - +text = "Alvor – encantadora vila. A aldeia piscatória de Alvor está situada no estuário do Rio Alvor e apesar da evolução constante do turismo no Algarve, mantém a sua arquitetura baixa e encanto da cidade velha, com ruas estreitas de paralelepípedos que nos levam até à Ria de Alvor, uma das belezas naturais mais impressionantes de Portugal. Há muitos hotéis em Alvor por onde escolher e adequar às exigências das suas férias, quanto a gosto e orçamento, bem como uma série de alojamento autossuficiente para aqueles que preferem ter um pouco mais de liberdade durante a sua estadia na Região de Portimão. Há muito para fazer e descobrir em Alvor, quer seja passar os seus dias descobrindo a rede de ruas desta encantadora vila de pescadores, explorar as lojas, ir para a praia para se divertir entre brincadeiras na areia e mergulhos no mar, ou descobrir a flora e fauna da área classificada da Ria de Alvor. O charme de Alvor não se esgota na Vila. Ficar hospedado em Alvor vai proporcionar-lhe momento mágicos entre paisagens de colinas, lagoas rasas e vistas panorâmicas sobre o Oceano Atlântico. Terá oportunidade de praticar o seu swing num dos campos de golfe de classe mundial e explorar as principais atrações históricas e alguns dos segredos mais bem escondidos do Algarve, nas proximidades, em Portimão e Mexilhoeira Grande. Consulte a lista dos nossos parceiros e escolha o hotel em Alvor, onde ficar durante as suas férias no Algarve." custom_kw_extractor = yake.KeywordExtractor(lan="pt") keywords = custom_kw_extractor.extract_keywords(text) - -for kw in keywords: - print(kw) ``` -#### Output -``` bash -('conta-me histórias', 0.006225012963810038) -('liaad do inesc', 0.01899063587015275) -('inesc tec', 0.01995432290332246) -('conta-me', 0.04513273690417472) -('histórias', 0.04513273690417472) -('prémio arquivo.pt', 0.05749361520927859) -('liaad', 0.07738867367929901) -('inesc', 0.07738867367929901) -('tec', 0.08109398065524037) -('xutos inspiram projeto', 0.08720742489353424) -('inspiram projeto premiado', 0.08720742489353424) -('adam jatwot docente', 0.09407053486771558) -('arquivo.pt', 0.10261392141666957) -('alípio jorge', 0.12190479662535166) -('ciências da universidade', 0.12368384021490342) -('ricardo campos investigador', 0.12789997272332762) -('politécnico de tomar', 0.13323587141127738) -('arian pasquali', 0.13323587141127738) -('vitor mangaravite', 0.13323587141127738) -('preservados da web', 0.13596322680882506) -``` - -## Related projects - -### YAKE! Mobile APP -YAKE! is now available on [Google Play](https://play.google.com/store/apps/details?id=com.yake.yake) - -### `pke` - python keyphrase extraction - -https://github.com/boudinfl/pke - `pke` is an **open source** python-based **keyphrase extraction** toolkit. It -provides an end-to-end keyphrase extraction pipeline in which each component can -be easily modified or extended to develop new models. `pke` also allows for -easy benchmarking of state-of-the-art keyphrase extraction models, and -ships with supervised models trained on the SemEval-2010 dataset (http://aclweb.org/anthology/S10-1004). - -Credits to https://github.com/boudinfl - -### `SparkNLP` - State of the Art Natural Language Processing framework -https://github.com/JohnSnowLabs/spark-nlp - `SparkNLP` from [John Snow Labs](https://www.johnsnowlabs.com/) is an open source framework with full Python, Scala, and Java Support. Check [their documentation](https://nlp.johnsnowlabs.com/docs/en/annotators#yakekeywordextraction), [demo](https://demo.johnsnowlabs.com/public/KEYPHRASE_EXTRACTION/) and [google colab](https://colab.research.google.com/github/JohnSnowLabs/spark-nlp-workshop/blob/master/tutorials/streamlit_notebooks/KEYPHRASE_EXTRACTION.ipynb). A video on how to use spark nlp with yake can also be found here: https://events.johnsnowlabs.com/john-snow-labs-nlu-become-a-data-science-superhero-with-one-line-of-python-code - -### `General Index` by Archive.org -https://archive.org/details/GeneralIndex - A catalogue of 19 billions of YAKE keywords extracted from 107 million papers. An article about the General Index project can also be found in [Nature](https://www.nature.com/articles/d41586-021-02895-8). +## Text Highlighting -### `textacy` - NLP, before and after spaCy +YAKE! includes a highlighting feature to mark keywords in text: -https://github.com/chartbeat-labs/textacy - `textacy` is a Python library for performing a variety of natural language processing (NLP) tasks, built on the high-performance spaCy library. among other features it supports keyword extration using YAKE. - -Credits to https://github.com/chartbeat-labs - - - -### `Annif` - Tool for automated subject indexing and classification -https://github.com/NatLibFi/Annif/ - `Annif` is a multi-algorithm automated subject indexing tool for libraries, archives and museums. This repository is used for developing a production version of the system, based on ideas from the initial prototype. Official website http://annif.org/. - -### `Portulan Clarin` - Services and data for researchers, innovators, students and language professionals -https://portulanclarin.net/workbench/liaad-yake/ - `Portulan Clarin` is a Research Infrastructure for the Science and Technology of Language, belonging to the Portuguese National Roadmap of Research Infrastructures of Strategic Relevance, and part of the international research infrastructure CLARIN ERIC. It includes a demo of YAKE! among many other language technologies. Official website https://portulanclarin.net/. - -## How to install Docker +```python +from yake.highlight import TextHighlighter -Here is the "just copy and paste" installations script for Docker in Ubuntu. Enjoy. +th = TextHighlighter(max_ngram_size=3) +highlighted_text = th.highlight(text, keywords) -```bash -# Install dependencies -sudo apt-get update -sudo apt-get install \ - apt-transport-https \ - ca-certificates \ - curl \ - software-properties-common - -# Add Docker repo -curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - -sudo apt-key fingerprint 0EBFCD88 -sudo add-apt-repository \ - "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ - $(lsb_release -cs) \ - stable" -sudo apt-get update - -# Install Docker -sudo apt-get install -y docker-ce - -# Start Docker Daemon -sudo service docker start - -# Add yourself to the Docker user group, otherwise docker will complain that -# it does not know if the Docker Daemon is running -sudo usermod -aG docker ${USER} - -# Install docker-compose -sudo curl -L "https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose -sudo chmod +x /usr/local/bin/docker-compose -source ~/.bashrc -docker-compose --version -echo "Done!" +# With custom HTML tags +custom_th = TextHighlighter( + max_ngram_size=3, + highlight_pre="", + highlight_post="" +) ``` -Credits to https://github.com/silvae86 for the Docker scripts. +## Where to Find YAKE! -## References -Please cite the following works when using YAKE +- 🌠Online demo: [http://yake.inesctec.pt](http://yake.inesctec.pt) +- 🔌 Documentation site: [https://tiagolv.github.io/yakerf/docs](https://tiagolv.github.io/yakerf/docs/--home) +- 📦 Python package: [https://github.com/LIAAD/yake_demo](https://github.com/LIAAD/yake_demo) +- 💻 Pypi: [https://pypi.org/project/yake/](https://pypi.org/project/yake/) -In-depth journal paper at Information Sciences Journal +## Citation -Campos, R., Mangaravite, V., Pasquali, A., Jatowt, A., Jorge, A., Nunes, C. and Jatowt, A. (2020). YAKE! Keyword Extraction from Single Documents using Multiple Local Features. In Information Sciences Journal. Elsevier, Vol 509, pp 257-289. [pdf](https://doi.org/10.1016/j.ins.2019.09.013) +If you use YAKE in your research, please cite the best suited: -ECIR'18 Best Short Paper +Campos, R., Mangaravite, V., Pasquali, A., Jatowt, A., Jorge, A., Nunes, C. and Jatowt, A. (2020). +YAKE! Keyword Extraction from Single Documents using Multiple Local Features. +Information Sciences Journal. Elsevier, Vol 509, pp 257-289. [pdf](https://link.springer.com/chapter/10.1007/978-3-319-76941-7_63) -Campos R., Mangaravite V., Pasquali A., Jorge A.M., Nunes C., and Jatowt A. (2018). A Text Feature Based Automatic Keyword Extraction Method for Single Documents. In: Pasi G., Piwowarski B., Azzopardi L., Hanbury A. (eds). Advances in Information Retrieval. ECIR 2018 (Grenoble, France. March 26 – 29). Lecture Notes in Computer Science, vol 10772, pp. 684 - 691. [pdf](https://link.springer.com/chapter/10.1007/978-3-319-76941-7_63) +Campos R., Mangaravite V., Pasquali A., Jorge A.M., Nunes C., and Jatowt A. (2018). +A Text Feature Based Automatic Keyword Extraction Method for Single Documents. +ECIR 2018. Lecture Notes in Computer Science, vol 10772, pp. 684-691. [pdf](https://link.springer.com/chapter/10.1007/978-3-319-76941-7_80) Campos R., Mangaravite V., Pasquali A., Jorge A.M., Nunes C., and Jatowt A. (2018). YAKE! Collection-independent Automatic Keyword Extractor. In: Pasi G., Piwowarski B., Azzopardi L., Hanbury A. (eds). Advances in Information Retrieval. ECIR 2018 (Grenoble, France. March 26 – 29). Lecture Notes in Computer Science, vol 10772, pp. 806 - 810. [pdf](https://link.springer.com/chapter/10.1007/978-3-319-76941-7_80) ## Awards -[ECIR'18](http://ecir2018.org) Best Short Paper + +🆠[ECIR'18](http://ecir2018.org) Best Short Paper \ No newline at end of file diff --git a/demo/packages.txt b/demo/packages.txt deleted file mode 100644 index 6092a9af..00000000 --- a/demo/packages.txt +++ /dev/null @@ -1,9 +0,0 @@ -matplotlib==3.3.1 -importlib-metadata==4.13.0 -git+https://github.com/LIAAD/yake -numpy==1.18.5 -pandas==1.0.5 -spacy==2.3.2 -wordcloud==1.8.0 -streamlit==0.64.0 -Pillow==7.2.0 diff --git a/demo/streamlit_app.py b/demo/streamlit_app.py deleted file mode 100644 index 81648284..00000000 --- a/demo/streamlit_app.py +++ /dev/null @@ -1,107 +0,0 @@ -import streamlit as st -import yake -import pandas as pd -import numpy as np -from wordcloud import WordCloud -import matplotlib.pyplot as plt -from spacy import displacy -import re - -st.write('', unsafe_allow_html=True) -HTML_WRAPPER = """
{}
""" - - -st.sidebar.title("Yet Another Keyword Extractor (YAKE)") -st.sidebar.markdown(""" -Unsupervised Approach for Automatic Keyword Extraction using Text Features. -https://liaad.github.io/yake/ -""" -) - -st.sidebar.markdown(""" -[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LIAAD/yake/blob/gh-pages/notebooks/YAKE_tutorial.ipynb) -""") - -st.sidebar.header('Parameters') - -#side bar parameters -max_ngram_size = st.sidebar.slider("Select max ngram size", 1, 10, 3) -deduplication_thresold = st.sidebar.slider("Select deduplication threshold", 0.5, 1.0, 0.9) -numOfKeywords = st.sidebar.slider("Select number of keywords to return", 1, 50, 10) -deduplication_algo = st.sidebar.selectbox('deduplication function', ('leve','jaro','seqm'),2) - - - -input_text_demo = [ - "Extracting keywords from texts has become a challenge for individuals and organizations as the information grows in complexity and size . The need to automate this task so that text can be processed in a timely and adequate manner has led to the emergence of automatic keyword extraction tools . Yake is a novel feature-based system for multi-lingual keyword extraction , which supports texts of different sizes, domain or languages. Unlike other approaches, Yake does not rely on dictionaries nor thesauri, neither is trained against any corpora. Instead, it follows an unsupervised approach which builds upon features extracted from the text, making it thus applicable to documents written in different languages without the need for further knowledge. This can be beneficial for a large number of tasks and a plethora of situations where access to training corpora is either limited or restricted.", - "Google is acquiring data science community Kaggle. Sources tell us that Google is acquiring Kaggle, a platform that hosts data science and machine learning competitions. Details about the transaction remain somewhat vague , but given that Google is hosting its Cloud Next conference in San Francisco this week, the official announcement could come as early as tomorrow. Reached by phone, Kaggle co-founder CEO Anthony Goldbloom declined to deny that the acquisition is happening. Google itself declined 'to comment on rumors'. Kaggle, which has about half a million data scientists on its platform, was founded by Goldbloom and Ben Hamner in 2010. The service got an early start and even though it has a few competitors like DrivenData, TopCoder and HackerRank, it has managed to stay well ahead of them by focusing on its specific niche. The service is basically the de facto home for running data science and machine learning competitions. With Kaggle, Google is buying one of the largest and most active communities for data scientists - and with that, it will get increased mindshare in this community, too (though it already has plenty of that thanks to Tensorflow and other projects). Kaggle has a bit of a history with Google, too, but that's pretty recent. Earlier this month, Google and Kaggle teamed up to host a $100,000 machine learning competition around classifying YouTube videos. That competition had some deep integrations with the Google Cloud Platform, too. Our understanding is that Google will keep the service running - likely under its current name. While the acquisition is probably more about Kaggle's community than technology, Kaggle did build some interesting tools for hosting its competition and 'kernels', too. On Kaggle, kernels are basically the source code for analyzing data sets and developers can share this code on the platform (the company previously called them 'scripts'). Like similar competition-centric sites, Kaggle also runs a job board, too. It's unclear what Google will do with that part of the service. According to Crunchbase, Kaggle raised $12.5 million (though PitchBook says it's $12.75) since its launch in 2010. Investors in Kaggle include Index Ventures, SV Angel, Max Levchin, Naval Ravikant, Google chief economist Hal Varian, Khosla Ventures and Yuri Milner", - "Genius quietly laid off a bunch of its engineers — now can it survive as a media company?. Genius, which raised $56.9 million on the promise that it would one day annotate the entire internet, has been losing its minds. In January, the company quietly laid off a quarter of its staff, with the bulk of the cuts coming from the engineering department. In a post on the Genius blog at the time, co-founder Tom Lehman told employees that Genius planned to shift its emphasis away from the annotation platform that once attracted top-tier investors in favor of becoming a more video-focused media company. 'After taking a careful look at the company and our priorities,' Lehman wrote, 'we’ve had to make some tough decisions about how we want to spend our resources. And unfortunately this meant that today we laid off some very talented people.' The company then took the unusual step of posting the Genius usernames of those it had laid off — 12 full-time and five part-time employees. 'WE NEEDED TO SHIFT RESOURCES FROM CAPTURING KNOWLEDGE... TOWARD PACKAGING AND DISTRIBUTING KNOWLEDGE.' At the same time, Lehman noted that the company was continuing to hire for roles in video and sales. The company recently redesigned its homepage with expanded space for editorial content and advertising. It has also been deepening its Behind the Lyrics partnership with Spotify, for which it contributes a mix of song lyrics and factoids that pop up in a slideshow format when you’re listening to popular songs. 'The change we made in January was in recognition of the fact that we needed to shift resources from capturing knowledge — which we've been doing almost exclusively for the past five years — toward packaging and distributing knowledge into easy-to-consume formats like video and Spotify Behind the Lyrics,' Lehman told The Verge. It’s not unusual for tech companies to transform over time, though typically they are loath to lay off engineers. But Genius’ shift is more dramatic than most: going from all-encompassing annotator of the internet to a more traditional media company model, chasing video views alongside an ever-growing number of well-capitalized competitors. The move illustrates the company’s difficulty attracting contributors — and an audience for their contributions — particularly outside of the music world. In an interview last week, Lehman said the company had turned to video in an effort to reach its core audience‚ which continues to be rap fans, beyond its website and mobile apps. 'Video makes it a little bit more accessible,' he said. 'I love the Genius website. One of my favorite websites. But it can be a little frustrating to use. You have to be really, really dedicated to learn everything about a song on Genius. You've got to be down to click and read a lot.' Genius’ videos to date have included interviews with artists about their craft, and a series where rappers perform original freestyle verses. One of Lehman’s favorite videos traces a whistle sample featured in a series of popular songs back to its origins in a Quentin Tarantino movie. Last week, Genius posted a video about rapper Lil Yachty learning how to make pizza. The company is also investing in original editorial content, aggregating news headlines, doing Q&As with artists like the Track Burnaz, and writing short profiles. ", -] - - - -windowSize = 1 - -#User text in content -st.header('Demo') - -selected_input_text = st.selectbox("Select sample text", input_text_demo) -text = st.text_area("Selected text", selected_input_text, 330) -language = "english" - -#use yake to extract keywords -custom_kw_extractor = yake.KeywordExtractor(lan=language, n=max_ngram_size, dedupLim=deduplication_thresold, dedupFunc=deduplication_algo, windowsSize=windowSize, top=numOfKeywords, features=None) -keywords = custom_kw_extractor.extract_keywords(text) - - - - -#get keywords and their position -ents = [] -text_lower = text.lower() - -keywords_list = str(keywords[0][0]) -for m in re.finditer(keywords_list, text_lower): - d = dict(start = m.start(), end = m.end(), label = "") - ents.append(d) - -for i in range(1, len(keywords)): - kwords = str(keywords[i][0]) - keywords_list += (', ' + kwords) - for m in re.finditer(kwords, text_lower): - d = dict(start = m.start(), end = m.end(), label = "") - ents.append(d) - -#sort the result by ents, as ent rule suggests -sort_ents = sorted(ents, key=lambda x: x["start"]) - -st.header('Output') - -result_view = st.radio("Choose visualization type",('Highlighting', 'Word cloud', 'Table'), index=0) -if result_view == 'Highlighting': - #use spacy to higlight the keywords - ex = [{"text": text, - "ents": sort_ents, - "title": None}] - - html = displacy.render(ex, style="ent", manual=True) - html = html.replace("\n", " ") - st.write(HTML_WRAPPER.format(html), unsafe_allow_html=True) -elif result_view == "Table": - #tabular data (columns: keywords, score) - df = pd.DataFrame(keywords, columns=("keywords","score")) - st.table(df) - -else: - #create and generate a word cloud image - wordcloud = WordCloud(width = 1000, height = 600, max_font_size = 80, - min_font_size=10, prefer_horizontal=1, - max_words=numOfKeywords, - background_color="white", - collocations=False, - regexp = r"\w[\w ']+").generate(keywords_list) - - #display the generated image - plt.imshow(wordcloud, interpolation='bilinear') - plt.axis("off") - st.pyplot(plt) diff --git a/docker/Dockerfiles/yake-server/Dockerfile b/docker/Dockerfiles/yake-server/Dockerfile deleted file mode 100644 index c0b896b1..00000000 --- a/docker/Dockerfiles/yake-server/Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -FROM library/python:3.7.1-alpine - -# change to temp dir -WORKDIR /temp - -# install git and build-base (GCC, etc.) -RUN apk update && apk upgrade && \ - apk add --no-cache bash git openssh && \ - apk add build-base - -RUN pip install flasgger - -# install requirements first to engage docker cache -RUN wget https://raw.githubusercontent.com/LIAAD/yake/master/requirements.txt -O requirements.txt -RUN pip install -r requirements.txt - -# install yake via pip -RUN pip install git+https://github.com/liaad/yake.git - -# Copy server startup script -COPY ./yake-rest-api.py /temp - -# Expose server port -ENV SERVER_PORT 5000 -EXPOSE "$SERVER_PORT" - -# set default command -CMD [ "python", "yake-rest-api.py" ] diff --git a/docker/Dockerfiles/yake-server/yake-rest-api.py b/docker/Dockerfiles/yake-server/yake-rest-api.py deleted file mode 100644 index 9a5cebf0..00000000 --- a/docker/Dockerfiles/yake-server/yake-rest-api.py +++ /dev/null @@ -1,139 +0,0 @@ -""" -Credits @arianpasquali -https://gist.githubusercontent.com/arianpasquali/16b2b0ab2095ee35dbede4dd2f4f8520/raw/ba4ea7da0d958fc4b1b2e694f45f17cc71d8238d/yake_rest_api.py - -The simple example serving YAKE as a rest api. - -instructions: - - pip install flasgger - pip install git+https://github.com/LIAAD/yake - - python yake_rest_api.py - -open http://127.0.0.1:5000/apidocs/ -""" - -from flask import Flask, jsonify, request - -from flasgger import Swagger - -try: - import simplejson as json -except ImportError: - import json -try: - from http import HTTPStatus -except ImportError: - import httplib as HTTPStatus - -import yake - -app = Flask(__name__) -app.config['SWAGGER'] = { - 'title': 'Yake API Explorer', - 'uiversion': 3 -} -swagger = Swagger(app) - -@swagger.validate('content') -@app.route('/yake/',methods=['POST']) -def handle_yake(): - """Example endpoint return a list of keywords using YAKE - --- - consumes: - - application/json - produces: - - application/json - parameters: - - name: content - in: body - description: content object - required: true - schema: - $ref: '#/definitions/content' - - requestBody: - description: Optional description in *Markdown* - required: true - content: - application/json: - schema: - id: content - type: object - - - responses: - 200: - description: Extract keywords from input text - schema: - $ref: '#/definitions/result' - - definitions: - content: - description: content object - properties: - text: - type: string - language: - type: string - max_ngram_size: - type: integer - minimum: 1 - number_of_keywords: - type: integer - minimum: 1 - required: - - text - - language - - max_ngram_size - - number_of_keywords - example: # Sample object - text: Sources tell us that Google is acquiring Kaggle, a platform that hosts data science and machine learning competitions. Details about the transaction remain somewhat vague , but given that Google is hosting its Cloud Next conference in San Francisco this week, the official announcement could come as early as tomorrow. Reached by phone, Kaggle co-founder CEO Anthony Goldbloom declined to deny that the acquisition is happening. Google itself declined 'to comment on rumors'. Kaggle, which has about half a million data scientists on its platform, was founded by Goldbloom and Ben Hamner in 2010. The service got an early start and even though it has a few competitors like DrivenData, TopCoder and HackerRank, it has managed to stay well ahead of them by focusing on its specific niche. The service is basically the de facto home for running data science and machine learning competitions. With Kaggle, Google is buying one of the largest and most active communities for data scientists - and with that, it will get increased mindshare in this community, too (though it already has plenty of that thanks to Tensorflow and other projects). Kaggle has a bit of a history with Google, too, but that's pretty recent. Earlier this month, Google and Kaggle teamed up to host a $100,000 machine learning competition around classifying YouTube videos. That competition had some deep integrations with the Google Cloud Platform, too. Our understanding is that Google will keep the service running - likely under its current name. While the acquisition is probably more about Kaggle's community than technology, Kaggle did build some interesting tools for hosting its competition and 'kernels', too. On Kaggle, kernels are basically the source code for analyzing data sets and developers can share this code on the platform (the company previously called them 'scripts'). Like similar competition centric sites, Kaggle also runs a job board, too. It's unclear what Google will do with that part of the service. According to Crunchbase, Kaggle raised $12.5 million (though PitchBook says it's $12.75) since its launch in 2010. Investors in Kaggle include Index Ventures, SV Angel, Max Levchin, Naval Ravikant, Google chief economist Hal Varian, Khosla Ventures and Yuri Milner - language: en - max_ngram_size: 3 - number_of_keywords: 10 - result: - type: array - items: - minItems: 0 - type: object - required: - - name - - value - properties: - ngram: - type: string - score: - type: number - """ - - try: - assert request.json["text"] , "Invalid text" - assert len(request.json["language"]) == 2, "Invalid language code" - assert int(request.json["max_ngram_size"]) , "Invalid max_ngram_size" - assert int(request.json["number_of_keywords"]) , "Invalid number_of_keywords" - - text = request.json["text"] - language = request.json["language"] - max_ngram_size = int(request.json["max_ngram_size"]) - number_of_keywords = int(request.json["number_of_keywords"]) - - my_yake = yake.KeywordExtractor(lan=language, - n=max_ngram_size, - top=number_of_keywords, - dedupLim=0.8, - windowsSize=2 - ) - - keywords = my_yake.extract_keywords(text) - result = [{"ngram":x[1] ,"score":x[0]} for x in keywords] - - return jsonify(result), HTTPStatus.OK - except IOError as e: - return jsonify("Language not supported"), HTTPStatus.BAD_REQUEST - except Exception as e: - return jsonify(str(e)), HTTPStatus.BAD_REQUEST - -if __name__ == "__main__": - app.run(host='0.0.0.0', debug=True) diff --git a/docker/Dockerfiles/yake/Dockerfile b/docker/Dockerfiles/yake/Dockerfile deleted file mode 100644 index 91adc6a7..00000000 --- a/docker/Dockerfiles/yake/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM library/python:3.7.1-alpine - -# change to temp dir -WORKDIR /temp - -# install git and build-base (GCC, etc.) -RUN apk update && apk upgrade && \ - apk add --no-cache bash git openssh && \ - apk add build-base - -# install yake via pip -RUN pip install git+https://github.com/liaad/yake.git - -# set default command -ENTRYPOINT ["yake"] diff --git a/docker/build.sh b/docker/build.sh deleted file mode 100755 index 1e58c1b8..00000000 --- a/docker/build.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash -if [ $# -eq 0 ] - then - tag='latest' - else - tag=$1 -fi - -INITIAL_DIR=$(pwd) -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" - -# get constants -source "$DIR/constants.sh" - -cd "$DIR/Dockerfiles/yake-server" -docker build -t "$YAKE_SERVER_IMAGE:$TAG" . -docker run -d -p $YAKE_PORT:$YAKE_PORT "$YAKE_SERVER_IMAGE:$TAG" - -cd "$DIR/Dockerfiles/yake" -docker build -t "$YAKE_IMAGE:$TAG" . -docker run -d "$YAKE_IMAGE:$TAG" - -docker ps -a - -cd $INITIAL_DIR diff --git a/docker/constants.sh b/docker/constants.sh deleted file mode 100755 index f06f4317..00000000 --- a/docker/constants.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -YAKE_PORT=5000 -YAKE_IMAGE="liaad/yake" -YAKE_SERVER_IMAGE="liaad/yake-server" -TAG="latest" diff --git a/docker/push_images.sh b/docker/push_images.sh deleted file mode 100755 index cbc967c1..00000000 --- a/docker/push_images.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" - -# get constants -source "$DIR/constants.sh" - -docker push "$YAKE_IMAGE:$TAG" -docker push "$YAKE_SERVER_IMAGE:$TAG" diff --git a/docker/test_image_calls.sh b/docker/test_image_calls.sh deleted file mode 100755 index 693a0423..00000000 --- a/docker/test_image_calls.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env bash -YAKE_PORT="5000" - -function wait_for_server_to_boot_on_port() -{ - local ip=$1 - local port=$2 - local text_to_find=$3 - - if [[ $ip == "" ]]; then - ip="127.0.0.1" - fi - local attempts=0 - local max_attempts=60 - - echo "Waiting for server on $ip:$port to boot up..." - response=$(curl -s $ip:$port) - - until $(curl --output /dev/null --silent --head --fail http://$ip:$port) || [[ $response == *$text_to_find* ]] || (( $attempts > $max_attempts )) ; do - ((attempts=attempts+1)) - echo "Waiting... ${attempts}/${max_attempts}" - sleep 1; - response=$(curl -s $ip:$port) - done - - if (( $attempts == $max_attempts )); - then - echo "Server on $ip:$port failed to start after $max_attempts" - elif (( $attempts < $max_attempts )); - then - echo "Server on $ip:$port started successfully at attempt (${attempts}/${max_attempts})" - fi -} - -# get directory of this script -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" - -# get constants -source "$DIR/constants.sh" -docker run -d -p $YAKE_PORT:$YAKE_PORT "$YAKE_SERVER_IMAGE:$TAG" - -wait_for_server_to_boot_on_port "127.0.0.1" "$YAKE_PORT" "404 Not Found" - -curl -X POST "http://127.0.0.1:5000/yake/" -H "accept: application/json" -H "Content-Type: application/json" \ --d @- <<'EOF' -{ - "language": "en", - "max_ngram_size": 2, - "number_of_keywords": 10, - "text": " - Sources tell us that Google is acquiring Kaggle, a platform that hosts data science and machine learning competitions. Details about the transaction remain somewhat vague , but given that Google is hosting its Cloud Next conference in San Francisco this week, the official announcement could come as early as tomorrow. Reached by phone, Kaggle co-founder CEO Anthony Goldbloom declined to deny that the acquisition is happening. Google itself declined 'to comment on rumors'. Kaggle, which has about half a million data scientists on its platform, was founded by Goldbloom and Ben Hamner in 2010. The service got an early start and even though it has a few competitors like DrivenData, TopCoder and HackerRank, it has managed to stay well ahead of them by focusing on its specific niche. The service is basically the de facto home for running data science and machine learning competitions. With Kaggle, Google is buying one of the largest and most active communities for data scientists - and with that, it will get increased mindshare in this community, too (though it already has plenty of that thanks to Tensorflow and other projects). Kaggle has a bit of a history with Google, too, but that's pretty recent. Earlier this month, Google and Kaggle teamed up to host a $100,000 machine learning competition around classifying YouTube videos. That competition had some deep integrations with the Google Cloud Platform, too. Our understanding is that Google will keep the service running - likely under its current name. While the acquisition is probably more about Kaggle's community than technology, Kaggle did build some interesting tools for hosting its competition and 'kernels', too. On Kaggle, kernels are basically the source code for analyzing data sets and developers can share this code on the platform (the company previously called them 'scripts'). Like similar competition centric sites, Kaggle also runs a job board, too. It's unclear what Google will do with that part of the service. According to Crunchbase, Kaggle raised $12.5 million (though PitchBook says it's $12.75) since its launch in 2010. Investors in Kaggle include Index Ventures, SV Angel, Max Levchin, Naval Ravikant, Google chief economist Hal Varian, Khosla Ventures and Yuri Milner - " -} -EOF - -# test -docker run "$YAKE_IMAGE:$TAG" -ti "Caffeine is a central nervous system (CNS) stimulant of the methylxanthine class.[10] It is the world's most widely consumed psychoactive drug. Unlike many other psychoactive substances, it is legal and unregulated in nearly all parts of the world. There are several known mechanisms of action to explain the effects of caffeine. The most prominent is that it reversibly blocks the action of adenosine on its receptor and consequently prevents the onset of drowsiness induced by adenosine. Caffeine also stimulates certain portions of the autonomic nervous system." \ No newline at end of file diff --git a/docs-site/.eslintrc.json b/docs-site/.eslintrc.json new file mode 100644 index 00000000..37224185 --- /dev/null +++ b/docs-site/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["next/core-web-vitals", "next/typescript"] +} diff --git a/docs-site/.gitignore b/docs-site/.gitignore new file mode 100644 index 00000000..55a12ae7 --- /dev/null +++ b/docs-site/.gitignore @@ -0,0 +1,28 @@ +# deps +/node_modules + +# generated content +.contentlayer +.content-collections +.source + +# test & build +/coverage +/.next/ +/out/ +/build +*.tsbuildinfo + +# misc +.DS_Store +*.pem +/.pnp +.pnp.js +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# others +.env*.local +.vercel +next-env.d.ts \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_noLang.txt b/docs-site/.nojekyll similarity index 100% rename from yake/StopwordsList/stopwords_noLang.txt rename to docs-site/.nojekyll diff --git a/docs-site/README.md b/docs-site/README.md new file mode 100644 index 00000000..2c0cec55 --- /dev/null +++ b/docs-site/README.md @@ -0,0 +1,17 @@ +# docs-site + +To access Documentation site run development server inside de docs-site folder: + +```bash +npm run dev +# or +pnpm dev +# or +yarn dev +``` + +Open http://localhost:3000 with your browser to see the result. + +## You can also simply access the site from the following link + +https://tiagolv.github.io/yakerf/docs diff --git a/docs-site/app/(home)/layout.tsx b/docs-site/app/(home)/layout.tsx new file mode 100644 index 00000000..1dd4684d --- /dev/null +++ b/docs-site/app/(home)/layout.tsx @@ -0,0 +1,7 @@ +import type { ReactNode } from 'react'; +import { HomeLayout } from 'fumadocs-ui/layouts/home'; +import { baseOptions } from '@/app/layout.config'; + +export default function Layout({ children }: { children: ReactNode }) { + return {children}; +} diff --git a/docs-site/app/(home)/page.tsx b/docs-site/app/(home)/page.tsx new file mode 100644 index 00000000..8d3c00bb --- /dev/null +++ b/docs-site/app/(home)/page.tsx @@ -0,0 +1,19 @@ +import Link from 'next/link'; + +export default function HomePage() { + return ( +
+

Welcome to YAKE! Documentation website

+

+ Open{' '} + + /docs + {' '} + and see the documentation. +

+
+ ); +} diff --git a/docs-site/app/config.ts b/docs-site/app/config.ts new file mode 100644 index 00000000..f4f1e199 --- /dev/null +++ b/docs-site/app/config.ts @@ -0,0 +1,2 @@ +// app/config.ts +export const basePath = process.env.NODE_ENV === 'production' ? '/yakerf' : ''; \ No newline at end of file diff --git a/docs-site/app/docs/[[...slug]]/page.tsx b/docs-site/app/docs/[[...slug]]/page.tsx new file mode 100644 index 00000000..3cb6d70a --- /dev/null +++ b/docs-site/app/docs/[[...slug]]/page.tsx @@ -0,0 +1,52 @@ +import { source } from '@/lib/source'; +import { + DocsPage, + DocsBody, + DocsDescription, + DocsTitle, +} from 'fumadocs-ui/page'; +import { notFound } from 'next/navigation'; +import { createRelativeLink } from 'fumadocs-ui/mdx'; +import { getMDXComponents } from '@/mdx-components'; + +export default async function Page(props: { + params: Promise<{ slug?: string[] }>; +}) { + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); + + const MDXContent = page.data.body; + + return ( + + {page.data.title} + {page.data.description} + + + + + ); +} + +export async function generateStaticParams() { + return source.generateParams(); +} + +export async function generateMetadata(props: { + params: Promise<{ slug?: string[] }>; +}) { + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); + + return { + title: page.data.title, + description: page.data.description, + }; +} diff --git a/docs-site/app/docs/layout.tsx b/docs-site/app/docs/layout.tsx new file mode 100644 index 00000000..a91d5585 --- /dev/null +++ b/docs-site/app/docs/layout.tsx @@ -0,0 +1,12 @@ +import { DocsLayout } from 'fumadocs-ui/layouts/docs'; +import type { ReactNode } from 'react'; +import { baseOptions } from '@/app/layout.config'; +import { source } from '@/lib/source'; + +export default function Layout({ children }: { children: ReactNode }) { + return ( + + {children} + + ); +} diff --git a/docs-site/app/global.css b/docs-site/app/global.css new file mode 100644 index 00000000..b6b2362a --- /dev/null +++ b/docs-site/app/global.css @@ -0,0 +1,122 @@ +@import 'tailwindcss'; +@import 'fumadocs-ui/css/neutral.css'; +@import 'fumadocs-ui/css/preset.css'; +@import "tw-animate-css"; + +@custom-variant dark (&:is(.dark *)); + +@theme inline { + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); +} + +:root { + --radius: 0.625rem; + --background: oklch(1 0 0); + --foreground: oklch(0.145 0 0); + --card: oklch(1 0 0); + --card-foreground: oklch(0.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.145 0 0); + --primary: oklch(0.205 0 0); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.97 0 0); + --secondary-foreground: oklch(0.205 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 0 0); + --accent: oklch(0.97 0 0); + --accent-foreground: oklch(0.205 0 0); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.922 0 0); + --input: oklch(0.922 0 0); + --ring: oklch(0.708 0 0); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.145 0 0); + --sidebar-primary: oklch(0.205 0 0); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.97 0 0); + --sidebar-accent-foreground: oklch(0.205 0 0); + --sidebar-border: oklch(0.922 0 0); + --sidebar-ring: oklch(0.708 0 0); +} + +.dark { + --background: oklch(0.145 0 0); + --foreground: oklch(0.985 0 0); + --card: oklch(0.205 0 0); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.205 0 0); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.922 0 0); + --primary-foreground: oklch(0.205 0 0); + --secondary: oklch(0.269 0 0); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.269 0 0); + --muted-foreground: oklch(0.708 0 0); + --accent: oklch(0.269 0 0); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.556 0 0); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.205 0 0); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.269 0 0); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.556 0 0); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/docs-site/app/layout.config.tsx b/docs-site/app/layout.config.tsx new file mode 100644 index 00000000..25fbf162 --- /dev/null +++ b/docs-site/app/layout.config.tsx @@ -0,0 +1,26 @@ +import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';; +import Image from 'next/image'; + +/** + * Shared layout configurations + * + * you can customise layouts individually from: + * Home Layout: app/(home)/layout.tsx + * Docs Layout: app/docs/layout.tsx + */ +export const baseOptions: BaseLayoutProps = { + nav: { + title: ( + <> + YAKE Logo + YAKE! + + ), + }, +}; \ No newline at end of file diff --git a/docs-site/app/layout.tsx b/docs-site/app/layout.tsx new file mode 100644 index 00000000..6b3a7b9a --- /dev/null +++ b/docs-site/app/layout.tsx @@ -0,0 +1,36 @@ +import { Metadata } from 'next'; +import { basePath } from './config'; +import './global.css'; + +import { RootProvider } from 'fumadocs-ui/provider'; +import { Inter } from 'next/font/google'; + +const inter = Inter({ + subsets: ['latin'], +}); + +export const metadata: Metadata = { + title: { + template: '%s | YAKE!', + default: 'YAKE! Documentation', + }, + description: 'Documentation for YAKE!', + icons: { + icon: `${basePath}/yakelogo.png`, + shortcut: `${basePath}/yakelogo.png`, + }, +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + {children} + + + ); +} diff --git a/docs-site/components.json b/docs-site/components.json new file mode 100644 index 00000000..4cfe3553 --- /dev/null +++ b/docs-site/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "", + "css": "app/global.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} \ No newline at end of file diff --git a/docs-site/components/ui/accordion.tsx b/docs-site/components/ui/accordion.tsx new file mode 100644 index 00000000..4a8cca46 --- /dev/null +++ b/docs-site/components/ui/accordion.tsx @@ -0,0 +1,66 @@ +"use client" + +import * as React from "react" +import * as AccordionPrimitive from "@radix-ui/react-accordion" +import { ChevronDownIcon } from "lucide-react" + +import { cn } from "@/lib/utils" + +function Accordion({ + ...props +}: React.ComponentProps) { + return +} + +function AccordionItem({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function AccordionTrigger({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + svg]:rotate-180", + className + )} + {...props} + > + {children} + + + + ) +} + +function AccordionContent({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + +
{children}
+
+ ) +} + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } diff --git a/docs-site/content/docs/--home.mdx b/docs-site/content/docs/--home.mdx new file mode 100644 index 00000000..5bbadd9f --- /dev/null +++ b/docs-site/content/docs/--home.mdx @@ -0,0 +1,100 @@ +--- +title: Yet Another Keyword Extractor (YAKE!) +icon: GitCompareArrows +--- +> **Info:** Unsupervised Approach for Automatic Keyword Extraction using Text Features. +--- +YAKE! is a light-weight unsupervised automatic keyword extraction method which rests on text statistical features extracted from single documents to select the most important keywords of a text. Our system does not need to be trained on a particular set of documents, neither it depends on dictionaries, external-corpus, size of the text, language or domain. + +[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/tiagolv/yakerf/blob/gh-pages/1YAKE.ipynb) +--- +## Background + +Extracting keywords from texts has become a challenge for individuals and organizations as the information grows in complexity and size. The need to automate this task so that texts can be processed in a timely and adequate manner has led to the emergence of automatic keyword extraction tools. Despite the advances, there is a clear lack of multilingual online tools to automatically extract keywords from single documents. Yake! is a novel feature-based system for multi-lingual keyword extraction, which supports texts of different sizes, domain or languages. Unlike other approaches, Yake! does not rely on dictionaries nor thesauri, neither is trained against any corpora. Instead, it follows an unsupervised approach which builds upon features extracted from the text, making it thus applicable to documents written in different languages without the need for further knowledge. This can be beneficial for a large number of tasks and a plethora of situations where the access to training corpora is either limited or restricted. + +## Main Features + +- Unsupervised approach +- Corpus-Independent +- Domain and Language Independent +- Single-Document + +## References + +If you use "YAKE" in a work that leads to a scientific publication, we would appreciate it if you would kindly cite it in your manuscript. + +- Campos, R., Mangaravite, V., Pasquali, A., Jatowt, A., Jorge, A., Nunes, C. and Jatowt, A. (2020). YAKE! Keyword Extraction from Single Documents using Multiple Local Features. In Information Sciences Journal. Elsevier, Vol 509, pp 257-289. [pdf](https://doi.org/10.1016/j.ins.2019.09.013) + +- Campos R., Mangaravite V., Pasquali A., Jorge A.M., Nunes C., and Jatowt A. (2018). A Text Feature Based Automatic Keyword Extraction Method for Single Documents. In: Pasi G., Piwowarski B., Azzopardi L., Hanbury A. (eds). Advances in Information Retrieval. ECIR 2018 (Grenoble, France. March 26 – 29). Lecture Notes in Computer Science, vol 10772, pp. 684 - 691. [pdf](https://link.springer.com/chapter/10.1007/978-3-319-76941-7_63) (ECIR'18 Best Short Paper) + +- Campos R., Mangaravite V., Pasquali A., Jorge A.M., Nunes C., and Jatowt A. (2018). YAKE! Collection-independent Automatic Keyword Extractor. In: Pasi G., Piwowarski B., Azzopardi L., Hanbury A. (eds). Advances in Information Retrieval. ECIR 2018 (Grenoble, France. March 26 – 29). Lecture Notes in Computer Science, vol 10772, pp. 806 - 810. [pdf](https://link.springer.com/chapter/10.1007/978-3-319-76941-7_80) + +## License + +Copyright (C) 2018, INESC TEC [license](https://github.com/LIAAD/yake/blob/master/LICENSE). + +## Contributing + +When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change. Read more about becoming a contributor in [our GitHub repo](https://github.com/LIAAD/yake/blob/master/CONTRIBUTING.rst). + +### Thank you to the contributors of YAKE! + + + +If you are feeling nostalgic you can access the old site [here](http://yake.inesctec.pt/). + +--- +
+

+ Back to top +

+

+ Copyright ©2018-{new Date().getFullYear()} INESC TEC. Distributed by an INESCTEC license. +

+
\ No newline at end of file diff --git a/docs-site/content/docs/-getting-started.mdx b/docs-site/content/docs/-getting-started.mdx new file mode 100644 index 00000000..bcdc0300 --- /dev/null +++ b/docs-site/content/docs/-getting-started.mdx @@ -0,0 +1,182 @@ +--- +title: Getting Started +icon: GitCompareArrows +--- +[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/tiagolv/yakerf/blob/gh-pages/1YAKE.ipynb) +## Installing YAKE! + +Installing Yake using pip: + +``` bash +pip install git+https://github.com/LIAAD/yake +``` +--- +## Usage (Command line) + +How to use it on your using the command line: + +``` bash +Usage: yake [OPTIONS] + +Options: + -ti, --text_input TEXT Input text, SURROUNDED by single quotes(\') + -i, --input_file TEXT Input file + -l, --language TEXT Language + -n, --ngram-size INTEGER Max size of the ngram. + -df, --dedup-func [leve|jaro|seqm] + Deduplication function. + -dl, --dedup-lim FLOAT Deduplication limiar. + -ws, --window-size INTEGER Window size. + -t, --top INTEGER Number of keyphrases to extract + -v, --verbose Gets detailed information (such as the score) + --help Show this message and exit. +``` + +### Keyword Deduplication Methods + +YAKE uses three methods to compute string similarity during keyword deduplication: + +#### 1. `levs` — Levenshtein Similarity + +* **What it is:** Measures the edit distance between two strings — how many operations (insertions, deletions, substitutions) are needed to turn one string into another. +* **Formula used:** + +```python +similarity = 1 - Levenshtein.distance(cand1, cand2) / max(len(cand1), len(cand2)) +``` + +* **Best for:** Very accurate for small changes (e.g., "house" vs "horse") +* **Performance:** Medium speed + +#### 2. `jaro` — Jaro Similarity + +* **What it is:** Measures similarity based on matching characters and their relative positions +* **Implementation:** Uses the `jellyfish` library +* **Best for:** More tolerant of transpositions (e.g., "maria" vs "maira") +* **Performance:** Fast + +#### 3. `seqm` — SequenceMatcher Ratio + +* **What it is:** Uses Python's built-in `difflib.SequenceMatcher` +* **Formula:** + +```python +ratio = 2 * M / T +``` +where `M` is the number of matching characters, and `T` is the total number of characters in both strings. + +* **Best for:** Good for detecting shared blocks in longer strings +* **Performance:** Fast + +#### Comparison Table + +| Method | Based on | Best for | Performance | +|--------|----------|----------|-------------| +| `levs` | Edit operations | Typos and small changes | Medium | +| `jaro` | Matching positions | Names and short strings with swaps | Fast | +| `seqm` | Common subsequences | General phrase similarity | Fast | + +#### Practical Examples + +| Compared Strings | `levs` | `jaro` | `seqm` | +|------------------|--------|--------|--------| +| "casa" vs "caso" | 0.75 | 0.83 | 0.75 | +| "machine" vs "mecine" | 0.71 | 0.88 | 0.82 | +| "apple" vs "a pple" | 0.8 | 0.93 | 0.9 | + +**Recommendation:** For general use with a good balance of speed and accuracy, `seqm` is a solid default (and it is YAKE's default). For stricter lexical similarity, choose `levs`. For names or when letter swaps are common, go with `jaro`. +## Usage (Python) + +How to use it using Python: + +``` python +import yake + +text = """Sources tell us that Google is acquiring Kaggle, a platform that hosts data science and machine learning +competitions. Details about the transaction remain somewhat vague, but given that Google is hosting its Cloud +Next conference in San Francisco this week, the official announcement could come as early as tomorrow. +Reached by phone, Kaggle co-founder CEO Anthony Goldbloom declined to deny that the acquisition is happening. +Google itself declined 'to comment on rumors'. Kaggle, which has about half a million data scientists on its platform, +was founded by Goldbloom and Ben Hamner in 2010. +The service got an early start and even though it has a few competitors like DrivenData, TopCoder and HackerRank, +it has managed to stay well ahead of them by focusing on its specific niche. +The service is basically the de facto home for running data science and machine learning competitions. +With Kaggle, Google is buying one of the largest and most active communities for data scientists - and with that, +it will get increased mindshare in this community, too (though it already has plenty of that thanks to Tensorflow +and other projects). Kaggle has a bit of a history with Google, too, but that's pretty recent. Earlier this month, +Google and Kaggle teamed up to host a $100,000 machine learning competition around classifying YouTube videos. +That competition had some deep integrations with the Google Cloud Platform, too. Our understanding is that Google +will keep the service running - likely under its current name. While the acquisition is probably more about +Kaggle's community than technology, Kaggle did build some interesting tools for hosting its competition +and 'kernels', too. On Kaggle, kernels are basically the source code for analyzing data sets and developers can +share this code on the platform (the company previously called them 'scripts'). +Like similar competition-centric sites, Kaggle also runs a job board, too. It's unclear what Google will do with +that part of the service. According to Crunchbase, Kaggle raised $12.5 million (though PitchBook says it's $12.75) +since its launch in 2010. Investors in Kaggle include Index Ventures, SV Angel, Max Levchin, Naval Ravikant, +Google chief economist Hal Varian, Khosla Ventures and Yuri Milner """ +``` + +### Simple usage using default parameters +```bash +kw_extractor = yake.KeywordExtractor() +keywords = kw_extractor.extract_keywords(text) + +for kw in keywords: + print(kw) +``` + +### Specifying custom parameters +```bash +language = "en" +max_ngram_size = 3 +deduplication_thresold = 0.9 +deduplication_algo = 'seqm' +windowSize = 1 +numOfKeywords = 20 + +kw_extractor = yake.KeywordExtractor(lan=language, + n=max_ngram_size, + dedupLim=deduplication_thresold, + dedupFunc=deduplication_algo, + windowsSize=windowSize, + top=numOfKeywords) + +keywords = kw_extractor.extract_keywords(text) + +for kw in keywords: + print(kw) +``` + +### Output +The lower the score, the more relevant the keyword is. +``` bash +('google', 0.026580863364597897) +('kaggle', 0.0289005976239829) +('ceo anthony goldbloom', 0.029946071606210194) +('san francisco', 0.048810837074825336) +('anthony goldbloom declined', 0.06176910090701819) +('google cloud platform', 0.06261974476422487) +('co-founder ceo anthony', 0.07357749587020043) +('acquiring kaggle', 0.08723571551039863) +('ceo anthony', 0.08915156857226395) +('anthony goldbloom', 0.09123482372372106) +('machine learning', 0.09147989238151344) +('kaggle co-founder ceo', 0.093805063905847) +('data', 0.097574333771058) +('google cloud', 0.10260128641464673) +('machine learning competitions', 0.10773000650607861) +('francisco this week', 0.11519915079240485) +('platform', 0.1183512305596321) +('conference in san', 0.12392066376108138) +('service', 0.12546743261462942) +('goldbloom', 0.14611408778815776) +``` +--- +
+

+ Back to top +

+

+ Copyright ©2018-{new Date().getFullYear()} INESC TEC. Distributed by an INESCTEC license. +

+
\ No newline at end of file diff --git a/docs-site/content/docs/-related-projects.mdx b/docs-site/content/docs/-related-projects.mdx new file mode 100644 index 00000000..c43caf2b --- /dev/null +++ b/docs-site/content/docs/-related-projects.mdx @@ -0,0 +1,36 @@ +--- +title: Related Projects +icon: GitCompareArrows +--- + +List of relevant projects using YAKE: + +- [SparkNLP](https://github.com/JohnSnowLabs/spark-nlp) by [John Snow Labs](https://www.johnsnowlabs.com/). +Open source framework with full Python, Scala, and Java Support. Check [their documentation](https://nlp.johnsnowlabs.com/docs/en/annotators#yakekeywordextraction), [demo](https://demo.johnsnowlabs.com/public/KEYPHRASE_EXTRACTION/) and [google colab](https://colab.research.google.com/github/JohnSnowLabs/spark-nlp-workshop/blob/master/tutorials/streamlit_notebooks/KEYPHRASE_EXTRACTION.ipynb). A video on how to use spark nlp with yake can also be found [here](https://events.johnsnowlabs.com/john-snow-labs-nlu-become-a-data-science-superhero-with-one-line-of-python-code): + +- [pke](https://github.com/boudinfl/pke) - Python Keyphrase Extraction module. +Ii is an open source python-based keyphrase extraction toolkit. It provides an end-to-end keyphrase extraction pipeline in which each component can be easily modified or extended to develop new models. Credits to Florian Boudin. + +- [Textacy](https://github.com/chartbeat-labs/textacy) - NLP, before and after spaCy. +Python library for performing a variety of natural language processing (NLP) tasks, built on the high-performance spaCy library. among other features it supports keyword extration using YAKE. + +- [General Index](https://archive.org/details/GeneralIndex) by Archive.org. +A catalogue of 19 billions of YAKE keywords extracted from 107 million papers. An article about the General Index project can also be found in [Nature](https://www.nature.com/articles/d41586-021-02895-8). + +- [Annif](https://github.com/NatLibFi/Annif) is a tool for automated subject indexing and classification. +Multi-algorithm automated subject indexing tool for libraries, archives and museums. This repository is used for developing a production version of the system, based on ideas from the initial prototype. Official [website](http://annif.org/). + +- [Portulan Clarin](https://portulanclarin.net/workbench/liaad-yake/) - Provides Sservices and data for researchers, innovators, students and language professionals +Research Infrastructure for the Science and Technology of Language, belonging to the Portuguese National Roadmap of Research Infrastructures of Strategic Relevance, and part of the international research infrastructure CLARIN ERIC. It includes a demo of YAKE! among many other language technologies. Official [website](https://portulanclarin.net/). + +- [Tell me stories](https://contamehistorias.pt/arquivopt) is a research project that allows users to automatically build news narratives based on news preserved by the [Portuguese Web Archive](https://arquivo.pt). + +--- +
+

+ Back to top +

+

+ Copyright ©2018-{new Date().getFullYear()} INESC TEC. Distributed by an INESCTEC license. +

+
\ No newline at end of file diff --git a/docs-site/content/docs/Documentation/core/Levenshtein.mdx b/docs-site/content/docs/Documentation/core/Levenshtein.mdx new file mode 100644 index 00000000..a2b54887 --- /dev/null +++ b/docs-site/content/docs/Documentation/core/Levenshtein.mdx @@ -0,0 +1,240 @@ +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion' + +# Levenshtein + +The `Levenshtein` class provides utilities for calculating edit distances and similarity ratios between strings using the Levenshtein algorithm. + +> **Info:** This documentation provides interactive code views for each method. Click on a function name to view its implementation. + +## Class Overview + +```python +class Levenshtein: + """ + Class for computing Levenshtein distance and similarity ratio. + + This class provides static methods to calculate the edit distance between + strings (how many insertions, deletions, or substitutions are needed to + transform one string into another) and to determine a normalized similarity + ratio between them. + + These metrics are widely used in fuzzy string matching, spell checking, + and approximate text similarity measurements. + """ +``` + +The `Levenshtein` class offers methods to measure the difference between two strings and calculate their similarity. + +## Static Methods + + + + + __ratio(distance, str_length) + + + ```python + @staticmethod + def __ratio(distance: float, str_length: int) -> float: + """ + Calculate the similarity ratio based on distance and string length. + + This method normalizes the Levenshtein distance into a similarity ratio + between 0 and 1, where 1 represents identical strings and 0 represents + completely different strings. + + Args: + distance (float): The Levenshtein distance between two strings. + str_length (int): The length of the longer string. + + Returns: + float: The similarity ratio, where higher values indicate greater similarity. + The range is [0.0, 1.0] where 1.0 means identical strings. + """ + return 1 - float(distance) / float(str_length) + ``` + + + + + + ratio(seq1, seq2) + + + ```python + @staticmethod + def ratio(seq1: str, seq2: str) -> float: + """ + Compute the similarity ratio between two strings. + + This is the main method for determining string similarity. It calculates + the Levenshtein distance and then converts it to a ratio representing + how similar the strings are. + + Args: + seq1 (str): The first string to compare. + seq2 (str): The second string to compare. + + Returns: + float: The similarity ratio between the two strings, ranging from 0.0 + (completely different) to 1.0 (identical). + """ + str_distance = Levenshtein.distance(seq1, seq2) + str_length = max(len(seq1), len(seq2)) + return Levenshtein.__ratio(str_distance, str_length) + ``` + + + + + + distance(seq1, seq2) + + + ```python + @staticmethod + def distance(seq1: str, seq2: str) -> int: + """ + Calculate the Levenshtein distance between two strings. + + This method implements the core Levenshtein algorithm, which calculates + the minimum number of single-character edits (insertions, deletions, or + substitutions) required to change one string into another. + + The algorithm uses dynamic programming with a matrix approach to efficiently + compute the minimum edit distance. + + Args: + seq1 (str): The first string to compare. + seq2 (str): The second string to compare. + + Returns: + int: The Levenshtein distance - the minimum number of edit operations + required to transform seq1 into seq2. + """ + # Create a matrix of size (len(seq1)+1) x (len(seq2)+1) + size_x = len(seq1) + 1 + size_y = len(seq2) + 1 + matrix = np.zeros((size_x, size_y)) + + # Initialize the first row and column of the matrix + for x in range(size_x): + matrix[x, 0] = x # Cost of deleting characters from seq1 + for y in range(size_y): + matrix[0, y] = y # Cost of inserting characters from seq2 + + # Fill the matrix using dynamic programming approach + for x in range(1, size_x): + for y in range(1, size_y): + # Check if the characters at current positions match + if seq1[x - 1] == seq2[y - 1]: + cost = 0 # No cost for matching characters + else: + cost = 1 # Cost of 1 for substitution + + # Calculate minimum cost among deletion, insertion, and substitution + matrix[x, y] = min( + matrix[x - 1, y] + 1, # Deletion (remove from seq1) + matrix[x, y - 1] + 1, # Insertion (add from seq2) + matrix[x - 1, y - 1] + cost, # Substitution or match + ) + + # Return the bottom-right value of the matrix as the final distance + return int(matrix[size_x - 1, size_y - 1]) + ``` + + + + +## Usage Guide + +### Distance Calculation + +The Levenshtein distance measures the minimum number of single-character edits (insertions, deletions, or substitutions) required to change one string into another. + +**Example:** +```python +from levenshtein import Levenshtein + +# Calculate the edit distance between two strings +distance = Levenshtein.distance("kitten", "sitting") +print(f"Levenshtein distance: {distance}") # Output: 3 +``` + +### Similarity Ratio + +The similarity ratio is a normalized measure between 0 and 1, where 1 means the strings are identical and 0 means they are completely different. + +**Example:** +```python +from levenshtein import Levenshtein + +# Calculate the similarity ratio between two strings +similarity = Levenshtein.ratio("kitten", "sitting") +print(f"Similarity ratio: {similarity:.4f}") # Output: 0.5714 +``` + +## Algorithm Explanation + +The Levenshtein distance algorithm uses dynamic programming to calculate the minimum edit distance between two strings: + +1. Initialize a matrix of size `(len(seq1)+1) × (len(seq2)+1)` +2. Fill the first row and column with increasing integers (0, 1, 2, ...) +3. For each cell in the matrix: + - If the corresponding characters match, the cost is 0; otherwise, it's 1 + - Calculate the minimum cost from three possible operations: + - Deletion: Value from the cell above + 1 + - Insertion: Value from the cell to the left + 1 + - Substitution: Value from the diagonal cell + cost +4. The bottom-right cell contains the final Levenshtein distance + +## Complete Usage Example + +```python +import numpy as np +from levenshtein import Levenshtein + +# Test strings +string1 = "natural language processing" +string2 = "neural language processing" + +# Calculate distance and similarity +distance = Levenshtein.distance(string1, string2) +similarity = Levenshtein.ratio(string1, string2) + +print(f"Strings:\n1: '{string1}'\n2: '{string2}'") +print(f"Levenshtein distance: {distance}") +print(f"Similarity ratio: {similarity:.4f}") + +# Example output: +# Strings: +# 1: 'natural language processing' +# 2: 'neural language processing' +# Levenshtein distance: 3 +# Similarity ratio: 0.8889 +``` + +## Performance Considerations + +- Time Complexity: O(m×n) where m and n are the lengths of the input strings +- Space Complexity: O(m×n) due to the matrix storage +- For very long strings, consider using optimized variants or approximate algorithms + +## Dependencies + +The `Levenshtein` class relies on: + +- `numpy`: For efficient matrix operations + + +## Applications + +Levenshtein distance is commonly used in: + +- Spell checking and correction +- DNA sequence alignment +- Plagiarism detection +- Fuzzy string matching +- Natural language processing +- Record linkage and data deduplication + diff --git a/docs-site/content/docs/Documentation/core/highlight.mdx b/docs-site/content/docs/Documentation/core/highlight.mdx new file mode 100644 index 00000000..6328964e --- /dev/null +++ b/docs-site/content/docs/Documentation/core/highlight.mdx @@ -0,0 +1,725 @@ +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion' + +# TextHighlighter + +The `TextHighlighter` module provides functionality to highlight specific keywords in text, supporting both single-word and multi-word highlighting with customizable markers. + +> **Info:** This documentation provides interactive code views for each method. Click on a function name to view its implementation. + +## Module Overview + +```python +""" +Module for highlighting text based on keywords. + +This module provides functionality to highlight specific keywords within text documents. +It handles both single word (one-gram) and multi-word (n-gram) keyword highlighting, +allowing for flexible text markup based on keyword extraction results. +""" + +import re +import logging +from dataclasses import dataclass +from typing import List + +DEFAULT_HIGHLIGHT_PRE = "" +DEFAULT_HIGHLIGHT_POST = "" +``` + +## Data class + +### NgramData + + + + + NgramData + + + ```python + @dataclass + class NgramData: + """ + Data structure to hold n-gram processing results. + + This class stores the results of n-gram identification for highlighting, + including the list of words and how they are split within keywords. + + Attributes: + word_list: List of words that form the n-gram + split_kw_list: List of lists containing the split keywords + """ + + word_list: List[str] + split_kw_list: List[List[str]] + ``` + + + + +A data class to store n-gram processing results containing: +- `word_list`: List of extracted words that form the n-gram +- `split_kw_list`: List of lists containing the split keywords for processing + +## Constructor + + + + + __init__(max_ngram_size, highlight_pre=DEFAULT_HIGHLIGHT_PRE, highlight_post=DEFAULT_HIGHLIGHT_POST) + + + ```python + def __init__( + self, + max_ngram_size, + highlight_pre=DEFAULT_HIGHLIGHT_PRE, + highlight_post=DEFAULT_HIGHLIGHT_POST, + ): + """ + TextHighlighter constructor. Define highlight text snippets. + + Args: + max_ngram_size: Specifies the maximum ngram size in the keywords. + highlight_pre: Specifies the text before a highlighted term. Defaults to . + highlight_post: Specifies the text after a highlighted term. Defaults to . + """ + self.highlight_pre = highlight_pre + self.highlight_post = highlight_post + self.max_ngram_size = max_ngram_size + ``` + + + + +**Parameters:** +- `max_ngram_size` (int): Maximum size of n-grams to consider for highlighting +- `highlight_pre` (str, optional): Text to insert before highlighted terms (default: ``) +- `highlight_post` (str, optional): Text to insert after highlighted terms (default: ``) + +## Core Methods + + + + + highlight(text, keywords) + + + ```python + def highlight(self, text, keywords): + """ + Highlights keywords in the given text. + + This is the main entry point for text highlighting. It processes the text + and adds highlight markers around identified keywords. + + Args: + text: The original text to be processed. + keywords: A list of keywords to highlight. + Each keyword can be a string or a tuple where the first element is the keyword. + + Returns: + The text with highlighted keywords. + """ + n_text = "" + if len(keywords) > 0: + kw_list = keywords + if isinstance(keywords[0], tuple): + kw_list = [x[0] for x in keywords] + text = text.strip() + if self.max_ngram_size == 1: + n_text = self.format_one_gram_text(text, kw_list) + else: + n_text = self.format_n_gram_text(text, kw_list) + return n_text + ``` + + + + + + format_one_gram_text(text, relevant_words_array) + + + ```python + def format_one_gram_text(self, text, relevant_words_array): + """ + Formats text for one-gram highlighting. + + Processes text to highlight individual words that match the keywords, + handling punctuation and maintaining the original text structure. + + Args: + text: The text to process + relevant_words_array: Keywords to highlight + + Returns: + Formatted text with highlighted keywords + """ + text_tokens = text.replace("\n", " ").split(" ") + relevant_words_array = [kw.lower() for kw in relevant_words_array] + try: + for tk, token in enumerate(text_tokens): + kw = re.sub(r'[!",:.;?()]$|^[!",:.;?()]|\W[!",:.;?()]', "", token) + if kw.lower() in relevant_words_array: + text_tokens[tk] = token.replace( + kw, f"{self.highlight_pre}{kw}{self.highlight_post}" + ) + except re.error as e: + logging.error("Regex error: %s", e) + return " ".join(text_tokens) + ``` + + + + + + format_n_gram_text(text, relevant_words_array) + + + ```python + def format_n_gram_text(self, text, relevant_words_array): + """ + Formats text for n-gram highlighting. + + Processes text to highlight multi-word phrases that match keywords, + maintaining proper context and handling overlapping keywords. + + Args: + text: The text to process + relevant_words_array: Keywords to highlight + + Returns: + Formatted text with highlighted keywords + """ + text_tokens = text.replace("\n", " ").split(" ") + relevant_words_array = [kw.lower() for kw in relevant_words_array] + + y = 0 + final_splited_text = [] + + while y < len(text_tokens): + n_gram_data = self.find_relevant_ngrams( + y, text_tokens, relevant_words_array + ) + + n_gram_word_list, splited_n_gram_kw_list = n_gram_data + + if n_gram_word_list: + context = { + "splited_n_gram_kw_list": splited_n_gram_kw_list, + "relevant_words_array": relevant_words_array, + "final_splited_text": final_splited_text, + } + y, new_expression = self.process_ngrams( + text_tokens, y, n_gram_word_list, context + ) + final_splited_text.append(new_expression) + else: + final_splited_text.append(text_tokens[y]) + y += 1 + + return " ".join(final_splited_text) + ``` + + + + + + find_relevant_ngrams(position, text_tokens, relevant_words_array) + + + ```python + def find_relevant_ngrams(self, position, text_tokens, relevant_words_array): + """ + Finds relevant n-grams in the text. + + Identifies potential keywords at the current position by looking ahead + for matches with the provided keywords. + + Args: + position: Current position in text tokens + text_tokens: List of tokens from the text + relevant_words_array: Keywords to highlight + + Returns: + Tuple containing n-gram word list and split n-gram keyword list + """ + + ngram_data = self._find_more_relevant_helper( + position, text_tokens, relevant_words_array + ) + + return ngram_data + ``` + + + + + + process_ngrams(text_tokens, position, n_gram_word_list, context) + + + ```python + def process_ngrams(self, text_tokens, position, n_gram_word_list, context): + """ + Processes n-grams and updates the final text. + + Handles the replacing of n-grams with their highlighted versions, + distinguishing between single-word and multi-word keywords. + + Args: + text_tokens: List of tokens from the text + position: Current position in text tokens + n_gram_word_list: List of n-gram words + context: Dictionary containing split n-gram keywords, + relevant words array, and final split text + + Returns: + Tuple containing new position and new expression + """ + if len(n_gram_word_list[0].split(" ")) == 1: + position, new_expression = self.replace_token( + text_tokens, position, n_gram_word_list + ) + else: + ctx = self._create_ngram_context( + n_gram_word_list, + context["splited_n_gram_kw_list"], + context["relevant_words_array"], + context["final_splited_text"], + ) + position, new_expression = self._process_multi_word_ngrams_helper( + text_tokens, position, ctx + ) + + return position, new_expression + ``` + + + + + + replace_token(text_tokens, position, n_gram_word_list) + + + ```python + def replace_token(self, text_tokens, position, n_gram_word_list): + """ + Replaces tokens in text with highlighted versions. + + Performs the actual replacement of keywords with their highlighted + versions, handling punctuation and maintaining text structure. + + Args: + text_tokens: List of tokens from the text + position: Current position in text tokens + n_gram_word_list: List of n-gram words + + Returns: + Tuple containing new position and new expression + """ + if not n_gram_word_list: + return position + 1, text_tokens[position] + + num_tokens = len(n_gram_word_list[0].split(" ")) + + if position + num_tokens > len(text_tokens): + num_tokens = len(text_tokens) - position + + txt = " ".join(text_tokens[position : position + num_tokens]) + kw_cleaned = re.sub(r'[!",:.;?()]$|^[!",:.;?()]|\W[!",:.;?()]', "", txt) + new_expression = txt.replace( + kw_cleaned, + f"{self.highlight_pre}{n_gram_word_list[0]}{self.highlight_post}", + ) + + return position + num_tokens, new_expression + ``` + + + + +## Helper Methods + + + + + _find_more_relevant_helper(position, text_tokens, relevant_words_array) + + + ```python + def _find_more_relevant_helper(self, position, text_tokens, relevant_words_array): + """ + Helper method for finding relevant n-gram words. + + Checks all possible n-grams starting at the current position and + identifies matches with the provided keywords. + + Args: + position: Current position in text tokens + text_tokens: List of tokens from the text + relevant_words_array: Keywords to highlight + + Returns: + NgramData containing keyword list and split n-gram word list + """ + temporary_list = [] + temporary_list_two = [] + kw_list = [] + splited_n_gram_word_list = [] + + for i in range(self.max_ngram_size): + if position + i < len(text_tokens): + temporary_list.append(text_tokens[position : position + i + 1]) + k = re.sub( + r'[!",:.;?()]$|^[!",:.;?()]|\W[!",:.;?()]', + "", + " ".join(temporary_list[i]), + ) + if k.lower() in relevant_words_array: + temporary_list_two.append(k) + + if temporary_list_two: + sorted_temp = sorted( + temporary_list_two, key=lambda x: relevant_words_array.index(x.lower()) + ) + kw_list.append(sorted_temp[0]) + splited_n_gram_word_list.append(kw_list[0].split()) + + return kw_list, splited_n_gram_word_list + ``` + + + + + + _create_ngram_context(n_gram_word_list, splited_n_gram_kw_list, relevant_words_array, final_splited_text) + + + ```python + def _create_ngram_context( + self, + n_gram_word_list, + splited_n_gram_kw_list, + relevant_words_array, + final_splited_text, + ): + """ + Creates a context object for n-gram processing. + + Bundles all the necessary information for processing multi-word + ngrams into a single context dictionary. + + Args: + n_gram_word_list: List of n-gram words + splited_n_gram_kw_list: List of split n-gram keywords + relevant_words_array: Keywords to highlight + final_splited_text: List of processed text tokens + + Returns: + Dictionary with context information + """ + return { + "n_gram_word_list": n_gram_word_list, + "splited_n_gram_kw_list": splited_n_gram_kw_list, + "relevant_words_array": relevant_words_array, + "final_splited_text": final_splited_text, + } + ``` + + + + + + _process_multi_word_ngrams_helper(text_tokens, position, ctx) + + + ```python + def _process_multi_word_ngrams_helper(self, text_tokens, position, ctx): + """ + Helper method for processing multi-word n-grams. + + Handles the complex logic of identifying and highlighting + multi-word phrases in the text. + + Args: + text_tokens: List of tokens from the text + position: Current position in text tokens + ctx: Context dictionary with processing information + + Returns: + Tuple containing new position and new expression + """ + kw_list = [] + n_gram_word_list = ctx["n_gram_word_list"] + splited_n_gram_kw_list = ctx["splited_n_gram_kw_list"] + relevant_words_array = ctx["relevant_words_array"] + final_splited_text = ctx["final_splited_text"] + + splited_one = n_gram_word_list[0].split() + + for len_kw in range(len(splited_one)): + if position + len_kw < len(text_tokens): + self._update_kw_list( + position + len_kw, + text_tokens, + relevant_words_array, + { + "kw_list": kw_list, + "splited_n_gram_kw_list": splited_n_gram_kw_list, + }, + ) + + if not kw_list: + return position + 1, text_tokens[position] + + min_score_word = min( + kw_list, key=lambda x: relevant_words_array.index(x.lower()) + ) + + if kw_list.index(min_score_word) == 0: + term_list = [min_score_word] + position, new_expression = self.replace_token( + text_tokens, position, term_list + ) + else: + terms_ctx = { + "splited_n_gram_kw_list": splited_n_gram_kw_list, + "min_score_word": min_score_word, + "relevant_words_array": relevant_words_array, + "final_splited_text": final_splited_text, + } + position, new_expression = self._process_relevant_terms_helper( + text_tokens, position, terms_ctx + ) + + return position, new_expression + ``` + + + + + + _update_kw_list(position, text_tokens, relevant_words_array, kw_dict) + + + ```python + def _update_kw_list(self, position, text_tokens, relevant_words_array, kw_dict): + """ + Updates the keyword list and split n-gram keyword list. + + Identifies relevant keywords at a given position and updates + the provided lists with the findings. + + Args: + position: Current position in text tokens + text_tokens: List of tokens from the text + relevant_words_array: Keywords to highlight + kw_dict: Dictionary containing 'kw_list' and 'splited_n_gram_kw_list' + """ + ngram_result = self._find_more_relevant_helper( + position, text_tokens, relevant_words_array + ) + new_kw_list, new_split_list = ngram_result + kw_dict["kw_list"].extend(new_kw_list) + if new_split_list: + kw_dict["splited_n_gram_kw_list"].extend(new_split_list) + ``` + + + + + + _process_relevant_terms_helper(text_tokens, position, ctx) + + + ```python + def _process_relevant_terms_helper(self, text_tokens, position, ctx): + """ + Helper method for processing relevant terms. + + Handles the complex logic of determining which terms to highlight + when multiple options are available. + + Args: + text_tokens: List of tokens from the text + position: Current position in text tokens + ctx: Context dictionary with processing information + + Returns: + Tuple containing new position and new expression + """ + splited_n_gram_kw_list = ctx["splited_n_gram_kw_list"] + min_score_word = ctx["min_score_word"] + relevant_words_array = ctx["relevant_words_array"] + final_splited_text = ctx["final_splited_text"] + + if not splited_n_gram_kw_list: + return position + 1, text_tokens[position] + + index_of_more_relevant = splited_n_gram_kw_list[0].index( + min_score_word.split()[0] + ) + temporal_kw = " ".join(splited_n_gram_kw_list[0][:index_of_more_relevant]) + + if temporal_kw.lower() in relevant_words_array: + try: + handle_ctx = { + "temporal_kw": temporal_kw, + "relevant_words_array": relevant_words_array, + "final_splited_text": final_splited_text, + } + return self._handle_temporal_keyword(text_tokens, position, handle_ctx) + except ValueError as e: + print(f"Error: {e}") + term_list = [temporal_kw] + position, new_expression = self.replace_token( + text_tokens, position, term_list + ) + else: + nonrelevant_ctx = { + "splited_n_gram_kw_list": splited_n_gram_kw_list, + "index_of_more_relevant": index_of_more_relevant, + "relevant_words_array": relevant_words_array, + } + position, new_expression = self._handle_nonrelevant_temporal_keyword( + text_tokens, position, nonrelevant_ctx + ) + + return position, new_expression + ``` + + + + + + _handle_temporal_keyword(text_tokens, position, ctx) + + + ```python + def _handle_temporal_keyword(self, text_tokens, position, ctx): + """ + Helper method for handling temporal keywords. + + Determines how to highlight keywords that may span across + multiple tokens or have temporal relationships. + + Args: + text_tokens: List of tokens from the text + position: Current position in text tokens + ctx: Context dictionary with processing information + + Returns: + Tuple containing new position and new expression + """ + temporal_kw = ctx["temporal_kw"] + relevant_words_array = ctx["relevant_words_array"] + final_splited_text = ctx["final_splited_text"] + + if not final_splited_text: + term_list = [temporal_kw] + return self.replace_token(text_tokens, position, term_list) + + last_item = final_splited_text[-1] + combined_kw = f"{last_item} {temporal_kw}" + + if ( + combined_kw.lower() in relevant_words_array + and relevant_words_array.index(temporal_kw.lower()) + > relevant_words_array.index(combined_kw.lower()) + and not re.findall(self.highlight_pre, last_item) + ): + term_list = [combined_kw] + del final_splited_text[-1] + position -= 1 + position, new_expression = self.replace_token( + text_tokens, position, term_list + ) + else: + term_list = [temporal_kw] + position, new_expression = self.replace_token( + text_tokens, position, term_list + ) + + return position, new_expression + ``` + + + + + + _handle_nonrelevant_temporal_keyword(text_tokens, position, ctx) + + + ```python + def _handle_nonrelevant_temporal_keyword(self, text_tokens, position, ctx): + """ + Helper method for handling non-relevant temporal keywords. + + Processes keywords that are part of larger phrases but not + relevant on their own. + + Args: + text_tokens: List of tokens from the text + position: Current position in text tokens + ctx: Context dictionary with processing information + + Returns: + Tuple containing new position and new expression + """ + splited_n_gram_kw_list = ctx["splited_n_gram_kw_list"] + index_of_more_relevant = ctx["index_of_more_relevant"] + relevant_words_array = ctx["relevant_words_array"] + + if not splited_n_gram_kw_list: + return position + 1, text_tokens[position] + + for tmp_kw in splited_n_gram_kw_list[0][:index_of_more_relevant]: + if tmp_kw.lower() in relevant_words_array: + term_list = [tmp_kw] + return self.replace_token(text_tokens, position, term_list) + + return position + 1, text_tokens[position] + ``` + + + + +## Usage Example + +```python +from yake.highlight import TextHighlighter + +# Sample text to process +text = "Natural language processing is a field of artificial intelligence that focuses on interactions between computers and human language." + +# Keywords to highlight +keywords = ["natural language processing", "artificial intelligence", "computers"] + +# Initialize the highlighter with maximum n-gram size of 3 +highlighter = TextHighlighter(max_ngram_size=3) + +# Get highlighted text +highlighted_text = highlighter.highlight(text, keywords) +print(highlighted_text) +# Output: "Natural language processing is a field of artificial intelligence that focuses on interactions between computers and human language." + +# Custom highlighting markers +custom_highlighter = TextHighlighter( + max_ngram_size=3, + highlight_pre="**", + highlight_post="**" +) +custom_highlighted = custom_highlighter.highlight(text, keywords) +print(custom_highlighted) +# Output: "**Natural language processing** is a field of **artificial intelligence** that focuses on interactions between **computers** and human language." +``` + +## Dependencies + +The `TextHighlighter` module relies on: +- `re`: For regular expression operations in text processing +- `logging`: For error handling and reporting +- `dataclasses`: For defining the `NgramData` dataclass +- `typing`: For type annotations \ No newline at end of file diff --git a/docs-site/content/docs/Documentation/core/yake.mdx b/docs-site/content/docs/Documentation/core/yake.mdx new file mode 100644 index 00000000..2dc6cbb2 --- /dev/null +++ b/docs-site/content/docs/Documentation/core/yake.mdx @@ -0,0 +1,414 @@ +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion' + +# KeywordExtractor Class + +The `KeywordExtractor` class is the main entry point for YAKE (Yet Another Keyword Extractor), providing a simple API to extract meaningful keywords from textual content. + +> **Info:** This documentation provides interactive code views for each method. Click on a function name to view its implementation. + +## Module Overview + +```python +""" +Keyword extraction module for YAKE. + +This module provides the KeywordExtractor class which serves as the main entry point +for the YAKE keyword extraction algorithm. It handles configuration, stopword loading, +deduplication of similar keywords, and the entire extraction pipeline from raw text +to ranked keywords. +""" + +import os +import jellyfish +from yake.data import DataCore +from .Levenshtein import Levenshtein +``` + +The `KeywordExtractor` class handles the configuration, preprocessing, and extraction of keywords from text documents using statistical features without relying on dictionaries or external corpora. + +## Constructor + + + + + __init__(**kwargs) + + + ```python + def __init__(self, **kwargs): + """ + Initialize the KeywordExtractor with configuration parameters. + + Args: + **kwargs: Configuration parameters including: + lan (str): Language for stopwords (default: "en") + n (int): Maximum n-gram size (default: 3) + dedup_lim (float): Similarity threshold for deduplication (default: 0.9) + dedup_func (str): Deduplication function: "seqm", "jaro", or "levs" (default: "seqm") + window_size (int): Size of word window for co-occurrence (default: 1) + top (int): Maximum number of keywords to extract (default: 20) + features (list): List of features to use for scoring (default: None = all features) + stopwords (set): Custom set of stopwords (default: None = use language-specific) + """ + # Initialize configuration dictionary with default values + self.config = { + "lan": kwargs.get("lan", "en"), + "n": kwargs.get("n", 3), + "dedup_lim": kwargs.get("dedup_lim", 0.9), + "dedup_func": kwargs.get("dedup_func", "seqm"), + "window_size": kwargs.get("window_size", 1), + "top": kwargs.get("top", 20), + "features": kwargs.get("features", None), + } + + # Load appropriate stopwords and deduplication function + self.stopword_set = self._load_stopwords(kwargs.get("stopwords")) + self.dedup_function = self._get_dedup_function(self.config["dedup_func"]) + ``` + + + + +**Parameters:** +- `lan` (str, optional): Language for stopwords (default: "en") +- `n` (int, optional): Maximum n-gram size (default: 3) +- `dedup_lim` (float, optional): Similarity threshold for deduplication (default: 0.9) +- `dedup_func` (str, optional): Deduplication function to use (default: "seqm") +- `window_size` (int, optional): Size of word window for co-occurrence (default: 1) +- `top` (int, optional): Maximum number of keywords to return (default: 20) +- `features` (list, optional): List of features to use for scoring (default: None = all features) +- `stopwords` (set, optional): Custom stopwords set (default: None, loads from language file) + +## Core Methods + + + + + extract_keywords(text) + + + ```python + def extract_keywords(self, text): + """ + Extract keywords from the given text. + + This function implements the complete YAKE keyword extraction pipeline: + + 1. Preprocesses the input text by normalizing whitespace + 2. Builds a data representation using DataCore, which: + - Tokenizes the text into sentences and words + - Identifies candidate n-grams (1 to n words) + - Creates a graph of term co-occurrences + 3. Extracts statistical features for single terms and n-grams + - For single terms: frequency, position, case, etc. + - For n-grams: combines features from constituent terms + 4. Filters candidates based on validity criteria (e.g., no stopwords at boundaries) + 5. Sorts candidates by their importance score (H), where lower is better + 6. Performs deduplication to remove similar candidates based on string similarity + 7. Returns the top k keywords with their scores + + The algorithm favors keywords that are statistically important but not common + stopwords, with scores reflecting their estimated relevance to the document. + Lower scores indicate more important keywords. + + Args: + text: Input text + + Returns: + List of (keyword, score) tuples sorted by score (lower is better) + + """ + # Handle empty input + if not text: + return [] + + # Normalize text by replacing newlines with spaces + text = text.replace("\n", " ") + + # Create a configuration dictionary for DataCore + core_config = { + "windows_size": self.config["window_size"], + "n": self.config["n"], + } + + # Initialize the data core with the text + dc = DataCore(text=text, stopword_set=self.stopword_set, config=core_config) + + # Build features for single terms and multi-word terms + dc.build_single_terms_features(features=self.config["features"]) + dc.build_mult_terms_features(features=self.config["features"]) + + # Collect and sort all valid candidates by score (lower is better) + result_set = [] + candidates_sorted = sorted( + [cc for cc in dc.candidates.values() if cc.is_valid()], key=lambda c: c.h + ) + + # If deduplication is disabled, return all candidates up to the limit + if self.config["dedup_lim"] >= 1.0: + return [(cand.unique_kw, cand.h) for cand in candidates_sorted][ + : self.config["top"] + ] + + # Perform deduplication by comparing candidates + for cand in candidates_sorted: + should_add = True + # Check if this candidate is too similar to any already selected + for h, cand_result in result_set: + if ( + self.dedup_function(cand.unique_kw, cand_result.unique_kw) + > self.config["dedup_lim"] + ): + should_add = False + break + + # Add candidate if it passes deduplication + if should_add: + result_set.append((cand.h, cand)) + + # Stop once we have enough candidates + if len(result_set) == self.config["top"]: + break + + # Format results as (keyword, score) tuples + return [(cand.kw, h) for (h, cand) in result_set] + ``` + + + + +**Parameters:** +- `text` (str): The text to extract keywords from + +**Returns:** +- list: A list of tuples containing (keyword, score) pairs, sorted by relevance (lower scores are better) + +## Helper Methods + + + + + _load_stopwords(stopwords) + + + ```python + def _load_stopwords(self, stopwords): + """ + Load stopwords from file or use provided set. + + This method handles the loading of language-specific stopwords from + the appropriate resource file, falling back to a language-agnostic + list if the specific language is not available. + + Args: + stopwords (set, optional): Custom set of stopwords to use + + Returns: + set: A set of stopwords for filtering non-content words + """ + # Use provided stopwords if available + if stopwords is not None: + return set(stopwords) + + # Determine the path to the appropriate stopword list + dir_path = os.path.dirname(os.path.realpath(__file__)) + local_path = os.path.join( + "StopwordsList", f"stopwords_{self.config['lan'][:2].lower()}.txt" + ) + + # Fall back to language-agnostic list if specific language not available + if not os.path.exists(os.path.join(dir_path, local_path)): + local_path = os.path.join("StopwordsList", "stopwords_noLang.txt") + + resource_path = os.path.join(dir_path, local_path) + + # Attempt to read the stopword file with UTF-8 encoding + try: + with open(resource_path, encoding="utf-8") as stop_file: + return set(stop_file.read().lower().split("\n")) + except UnicodeDecodeError: + # Fall back to ISO-8859-1 encoding if UTF-8 fails + print("Warning: reading stopword list as ISO-8859-1") + with open(resource_path, encoding="ISO-8859-1") as stop_file: + return set(stop_file.read().lower().split("\n")) + ``` + + + + + + _get_dedup_function(func_name) + + + ```python + def _get_dedup_function(self, func_name): + """ + Retrieve the appropriate deduplication function. + + Maps the requested string similarity function name to the corresponding + method implementation for keyword deduplication. + + Args: + func_name (str): Name of the deduplication function to use + + Returns: + function: Reference to the selected string similarity function + """ + # Map function names to their implementations + return { + "jaro_winkler": self.jaro, + "jaro": self.jaro, + "sequencematcher": self.seqm, + "seqm": self.seqm, + }.get(func_name.lower(), self.levs) + ``` + + + + +## Similarity Functions + + + + + jaro(cand1, cand2) + + + ```python + def jaro(self, cand1, cand2): + """ + Calculate Jaro similarity between two strings. + + A string metric measuring edit distance between two sequences, + with higher values indicating greater similarity. + + Args: + cand1 (str): First string to compare + cand2 (str): Second string to compare + + Returns: + float: Similarity score between 0.0 (different) and 1.0 (identical) + """ + return jellyfish.jaro(cand1, cand2) + ``` + + + + + + levs(cand1, cand2) + + + ```python + def levs(self, cand1, cand2): + """ + Calculate normalized Levenshtein similarity between two strings. + + Computes the Levenshtein distance and normalizes it by the length + of the longer string, returning a similarity score. + + Args: + cand1 (str): First string to compare + cand2 (str): Second string to compare + + Returns: + float: Similarity score between 0.0 (different) and 1.0 (identical) + """ + return 1 - Levenshtein.distance(cand1, cand2) / max(len(cand1), len(cand2)) + ``` + + + + + + seqm(cand1, cand2) + + + ```python + def seqm(self, cand1, cand2): + """ + Calculate sequence matcher ratio between two strings. + + Uses the Levenshtein ratio which measures the similarity between + two strings based on the minimum number of operations required + to transform one string into the other. + + Args: + cand1 (str): First string to compare + cand2 (str): Second string to compare + + Returns: + float: Similarity score between 0.0 (different) and 1.0 (identical) + """ + return Levenshtein.ratio(cand1, cand2) + ``` + + + + +## Usage Examples + +### Basic Usage + +```python +from yake import KeywordExtractor + +text = """ +Natural language processing (NLP) is a subfield of linguistics, computer science, and artificial intelligence +concerned with the interactions between computers and human language, in particular how to program computers +to process and analyze large amounts of natural language data. +""" + +# Simple example with default parameters +kw_extractor = KeywordExtractor() +keywords = kw_extractor.extract_keywords(text) + +# Print the keywords and their scores +for kw, score in keywords: + print(f"{kw}: {score:.4f}") +``` + +### Customized Usage + +```python +from yake import KeywordExtractor + +# Create a custom stopwords set +custom_stopwords = {"the", "a", "an", "in", "on", "at", "of", "for", "with"} + +# Initialize with custom parameters +kw_extractor = KeywordExtractor( + lan="en", # Language + n=2, # Maximum n-gram size + dedup_lim=0.8, # Deduplication threshold + dedup_func="jaro", # Deduplication function + window_size=2, # Window size + top=10, # Number of keywords to extract + stopwords=custom_stopwords +) + +text = "Machine learning is the study of computer algorithms that improve automatically through experience." +keywords = kw_extractor.extract_keywords(text) + +# Print the top 10 keywords +for kw, score in keywords: + print(f"{kw}: {score:.4f}") +``` + +## Deduplication Functions + +The `KeywordExtractor` supports multiple string similarity algorithms for deduplication: + +1. **Jaro-Winkler** ("jaro", "jaro_winkler"): Based on character matches with higher weights for prefix matches + +2. **Levenshtein Ratio** ("levs"): Based on Levenshtein edit distance normalized by string length + +3. **SequenceMatcher** ("seqm", "sequencematcher"): Based on Python's difflib sequence matching algorithm + +## Dependencies + +The module relies on: +- `os`: For file operations and path handling +- `jellyfish`: For Jaro-Winkler string similarity +- `yake.data.DataCore`: For core data representation +- `.Levenshtein`: For Levenshtein distance and ratio calculations \ No newline at end of file diff --git a/docs-site/content/docs/Documentation/data/composedword.mdx b/docs-site/content/docs/Documentation/data/composedword.mdx new file mode 100644 index 00000000..870e913f --- /dev/null +++ b/docs-site/content/docs/Documentation/data/composedword.mdx @@ -0,0 +1,603 @@ +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion' + +# ComposedWord + +The `ComposedWord` class represents multi-word terms in YAKE (Yet Another Keyword Extractor), providing the foundation for analyzing and scoring potential keyword phrases. + +> **Info:** This documentation provides interactive code views for each method. Click on a function name to view its implementation. + +## Class Overview + +```python +class ComposedWord: + """ + Representation of a multi-word term in the document. + + This class stores and aggregates information about multi-word keyword candidates, + calculating combined scores from the properties of their constituent terms. + It tracks statistics like term frequency, integrity, and provides methods to + validate whether a phrase is likely to be a good keyword. + + Attributes: + See property accessors below for available attributes. + """ +``` + +The `ComposedWord` class stores and aggregates information about multi-word keyword candidates, calculating combined scores from the properties of their constituent terms. It tracks statistics like term frequency, integrity, and provides methods to validate whether a phrase is likely to be a good keyword. + +## Constructor + + + + + __init__(terms) + + + ```python + def __init__(self, terms): + """ + Initialize a ComposedWord object representing a multi-word term. + + Args: + terms (list): List of tuples (tag, word, term_obj) representing + the individual words in this phrase. Can be None to + initialize an invalid candidate. + """ + # If terms is None, initialize an invalid candidate + if terms is None: + self.data = { + "start_or_end_stopwords": True, + "tags": set(), + "h": 0.0, + "tf": 0.0, + "kw": "", + "unique_kw": "", + "size": 0, + "terms": [], + "integrity": 0.0, + } + return + + # Basic initialization from terms + self.data = {} + + # Calculate derived properties + self.data["tags"] = set(["".join([w[0] for w in terms])]) + self.data["kw"] = " ".join([w[1] for w in terms]) + self.data["unique_kw"] = self.data["kw"].lower() + self.data["size"] = len(terms) + self.data["terms"] = [w[2] for w in terms if w[2] is not None] + self.data["tf"] = 0.0 + self.data["integrity"] = 1.0 + self.data["h"] = 1.0 + + # Check if the candidate starts or ends with stopwords + if len(self.data["terms"]) > 0: + self.data["start_or_end_stopwords"] = ( + self.data["terms"][0].stopword or self.data["terms"][-1].stopword + ) + else: + self.data["start_or_end_stopwords"] = True + ``` + + + + +**Parameters:** +- `terms` (list): A list of term tuples in the format `(tag, word, term_obj)` where: + - `tag` (str): The part-of-speech tag for the word + - `word` (str): The actual word text + - `term_obj` (SingleWord): The term object representation + +**Example:** +```python +from yake.data import ComposedWord + +# Create a composed word from term tuples +terms = [('n', 'natural', term_obj1), ('n', 'language', term_obj2)] +composed_word = ComposedWord(terms) + +# Create an invalid composed word +invalid_composed = ComposedWord(None) +``` + +## Core Methods + + + + + update_h(features=None, is_virtual=False) + + + ```python + def update_h(self, features=None, is_virtual=False): + """ + Update the term's score based on its constituent terms. + + Calculates a combined relevance score for the multi-word term by + aggregating scores of its constituent words, with special handling for + stopwords to improve keyword quality. + + Args: + features (list, optional): Specific features to use for scoring + is_virtual (bool): Whether this is a virtual candidate not in text + """ + sum_h = 0.0 + prod_h = 1.0 + + # Process each term in the phrase + for t, term_base in enumerate(self.terms): + # Handle non-stopwords directly + if not term_base.stopword: + sum_h += term_base.h + prod_h *= term_base.h + + # Handle stopwords according to configured weight method + else: + if STOPWORD_WEIGHT == "bi": + # BiWeight: use probabilities of adjacent term connections + prob_t1 = 0.0 + # Check connection with previous term + if t > 0 and term_base.g.has_edge( + self.terms[t - 1].id, self.terms[t].id + ): + prob_t1 = ( + term_base.g[self.terms[t - 1].id][self.terms[t].id]["tf"] + / self.terms[t - 1].tf + ) + + prob_t2 = 0.0 + # Check connection with next term + if t < len(self.terms) - 1 and term_base.g.has_edge( + self.terms[t].id, self.terms[t + 1].id + ): + prob_t2 = ( + term_base.g[self.terms[t].id][self.terms[t + 1].id]["tf"] + / self.terms[t + 1].tf + ) + + # Calculate combined probability and update scores + prob = prob_t1 * prob_t2 + prod_h *= 1 + (1 - prob) + sum_h -= 1 - prob + elif STOPWORD_WEIGHT == "h": + # HWeight: treat stopwords like normal words + sum_h += term_base.h + prod_h *= term_base.h + elif STOPWORD_WEIGHT == "none": + # None: ignore stopwords entirely + pass + + # Determine term frequency to use in scoring + tf_used = 1.0 + if features is None or "KPF" in features: + tf_used = self.tf + + # For virtual candidates, use mean frequency of constituent terms + if is_virtual: + tf_used = np.mean([term_obj.tf for term_obj in self.terms]) + + # Calculate final score (lower is better) + self.h = prod_h / ((sum_h + 1) * tf_used) + ``` + + + + + + is_valid() + + + ```python + def is_valid(self): + """ + Check if this candidate is a valid keyword phrase. + + A valid keyword phrase doesn't contain unusual characters or digits, + and doesn't start or end with stopwords. + + Returns: + bool: True if this is a valid keyword candidate, False otherwise + """ + is_valid = False + # Check that at least one tag sequence has no unusual characters or digits + for tag in self.tags: + is_valid = is_valid or ("u" not in tag and "d" not in tag) + + # A valid keyword cannot start or end with a stopword + return is_valid and not self.start_or_end_stopwords + ``` + + + + + + uptade_cand(cand) + + + ```python + def uptade_cand(self, cand): + """ + Update this candidate with data from another candidate. + + Merges tag information from another candidate representing + the same keyword phrase. + + Args: + cand (ComposedWord): Another instance of the same keyword to merge with + """ + # Add all tags from the other candidate to this one's tags + for tag in cand.tags: + self.tags.add(tag) + ``` + + + + + + get_composed_feature(feature_name, discart_stopword=True) + + + ```python + def get_composed_feature(self, feature_name, discart_stopword=True): + """ + Get composed feature values for the n-gram. + + This function aggregates a specific feature across all terms in the n-gram. + It computes the sum, product, and ratio of the feature values, optionally + excluding stopwords from the calculation. + + Args: + feature_name: Name of feature to get (must be an attribute of the term objects) + discard_stopword: Whether to exclude stopwords from calculation (True by default) + + Returns: + Tuple of (sum, product, ratio) for the feature where: + - sum: Sum of the feature values across all relevant terms + - product: Product of the feature values across all relevant terms + - ratio: Product divided by (sum + 1), a measure of feature consistency + """ + # Get feature values from each term, filtering stopwords if requested + list_of_features = [ + getattr(term, feature_name) + for term in self.terms + if (discart_stopword and not term.stopword) or not discart_stopword + ] + + # Calculate aggregate statistics + sum_f = sum(list_of_features) + prod_f = np.prod(list_of_features) + + # Return the three aggregated values + return (sum_f, prod_f, prod_f / (sum_f + 1)) + ``` + + + + + + build_features(params) + + + ```python + def build_features(self, params): + """ + Build features for machine learning or evaluation. + + Generates feature vectors that can be used for model training, + evaluation, or visualization of keyword properties. + + Args: + params (dict): Parameters for feature generation including: + - features (list): Features to include + - _stopword (list): Whether to consider stopwords [True, False] + - doc_id (str): Document identifier + - keys (list): Gold standard keywords for evaluation + - rel (bool): Whether to include relevance feature + - rel_approx (bool): Whether to include approximate relevance + - is_virtual (bool): Whether this is a virtual candidate + + Returns: + tuple: (features_list, column_names, matched_gold_standards) + """ + # Get feature configuration from parameters + features = params.get( + "features", ["wfreq", "wrel", "tf", "wcase", "wpos", "wspread"] + ) + _stopword = params.get("_stopword", [True, False]) + + # Use defaults if not provided + if features is None: + features = ["wfreq", "wrel", "tf", "wcase", "wpos", "wspread"] + if _stopword is None: + _stopword = [True, False] + + # Initialize feature collection + columns = [] + features_cand = [] + seen = set() + + # Add document identifier if provided + if params.get("doc_id") is not None: + columns.append("doc_id") + features_cand.append(params["doc_id"]) + + # Add gold standard match features if keys are provided + if params.get("keys") is not None: + # Exact match feature + if params.get("rel", True): + columns.append("rel") + if self.unique_kw in params["keys"] or params.get("is_virtual", False): + features_cand.append(1) + seen.add(self.unique_kw) + else: + features_cand.append(0) + + # Approximate match feature using string similarity + if params.get("rel_approx", True): + columns.append("rel_approx") + max_gold_ = ("", 0.0) + for gold_key in params["keys"]: + # Calculate normalized Levenshtein similarity + dist = 1.0 - jellyfish.levenshtein_distance( + gold_key, + self.unique_kw, + ) / max(len(gold_key), len(self.unique_kw)) + max_gold_ = (gold_key, dist) + features_cand.append(max_gold_[1]) + features_cand.append(max_gold_[1]) + + # Add basic candidate properties + columns.append("kw") + features_cand.append(self.unique_kw) + columns.append("h") + features_cand.append(self.h) + columns.append("tf") + features_cand.append(self.tf) + columns.append("size") + features_cand.append(self.size) + columns.append("is_virtual") + columns.append("is_virtual") + features_cand.append(int(params.get("is_virtual", False))) + + # Add all requested features with different stopword handling + for feature_name in features: + for discart_stopword in _stopword: + # Calculate aggregate feature metrics + (f_sum, f_prod, f_sum_prod) = self.get_composed_feature( + feature_name, discart_stopword=discart_stopword + ) + + # Add sum feature + columns.append( + f"{'n' if discart_stopword else ''}s_sum_K{feature_name}" + ) + features_cand.append(f_sum) + + # Add product feature + columns.append( + f"{'n' if discart_stopword else ''}s_prod_K{feature_name}" + ) + features_cand.append(f_prod) + + # Add sum-product feature + columns.append( + f"{'n' if discart_stopword else ''}s_sum_prod_K{feature_name}" + ) + features_cand.append(f_sum_prod) + + return (features_cand, columns, seen) + ``` + + + + + + update_h_old(features=None, is_virtual=False) + + + ```python + def update_h_old(self, features=None, is_virtual=False): + """ + Legacy method for updating the term's score. + + Preserved for backward compatibility but uses a slightly different + approach to calculate scores. + + Args: + features (list, optional): Specific features to use for scoring + is_virtual (bool): Whether this is a virtual candidate not in text + """ + sum_h = 0.0 + prod_h = 1.0 + + # Process each term in the phrase + for t, term_base in enumerate(self.terms): + # Skip terms with zero frequency in virtual candidates + if is_virtual and term_base.tf == 0: + continue + + # Handle stopwords with probability-based weighting + if term_base.stopword: + # Calculate probability of co-occurrence with previous term + prob_t1 = 0.0 + if term_base.g.has_edge(self.terms[t - 1].id, self.terms[t].id): + prob_t1 = ( + term_base.g[self.terms[t - 1].id][self.terms[t].id]["tf"] + / self.terms[t - 1].tf + ) + + # Calculate probability of co-occurrence with next term + prob_t2 = 0.0 + if term_base.g.has_edge(self.terms[t].id, self.terms[t + 1].id): + prob_t2 = ( + term_base.g[self.terms[t].id][self.terms[t + 1].id]["tf"] + / self.terms[t + 1].tf + ) + + # Update scores based on combined probability + prob = prob_t1 * prob_t2 + prod_h *= 1 + (1 - prob) + sum_h -= 1 - prob + else: + # Handle normal words directly + sum_h += term_base.h + prod_h *= term_base.h + + # Determine term frequency to use in scoring + tf_used = 1.0 + if features is None or "KPF" in features: + tf_used = self.tf + + # For virtual candidates, use mean frequency of constituent terms + if is_virtual: + tf_used = np.mean([term_obj.tf for term_obj in self.terms]) + + # Calculate final score (lower is better) + self.h = prod_h / ((sum_h + 1) * tf_used) + ``` + + + + +## Property Accessors + +The `ComposedWord` class uses a dictionary-based property system with property accessors for backward compatibility: + +### Basic Properties + +- `tags`: Set of POS tag combinations for this candidate +- `kw`: The original keyword text +- `unique_kw`: Lowercase version of the keyword for uniqueness checks +- `size`: Number of terms in this candidate +- `terms`: List of term objects in this candidate +- `start_or_end_stopwords`: Boolean indicating if the candidate starts or ends with stopwords + +```python +# Examples +pos_tags = composed_word.tags +keyword = composed_word.kw +unique_key = composed_word.unique_kw +term_count = composed_word.size +term_objects = composed_word.terms +has_stopword_boundary = composed_word.start_or_end_stopwords +``` + +### Scoring Properties + +- `tf`: Term frequency of this candidate +- `integrity`: Integrity score (default: 1.0) +- `h`: YAKE score for this candidate (lower is better) + +```python +# Examples +term_frequency = composed_word.tf +integrity_score = composed_word.integrity +yake_score = composed_word.h + +# The tf property is settable +composed_word.tf = 5.0 + +# The h property is settable +composed_word.h = 0.25 +``` + +## Key Algorithms + +### Candidate Validation + +Candidates are considered valid if: +1. They contain no undefined ("u") or discarded ("d") POS tags +2. They do not start or end with stopwords + +### Feature Composition + +When analyzing multi-word terms, the `ComposedWord` class composes features from its constituent terms: + +```python +def get_composed_feature(self, feature_name, discart_stopword=True): + """ + Get composed feature values for the n-gram. + """ + # Get feature values from each term, filtering stopwords if requested + list_of_features = [ + getattr(term, feature_name) + for term in self.terms + if (discart_stopword and not term.stopword) or not discart_stopword + ] + + # Calculate aggregate statistics + sum_f = sum(list_of_features) + prod_f = np.prod(list_of_features) + + # Return the three aggregated values: sum, product, and product/(sum+1) + return (sum_f, prod_f, prod_f / (sum_f + 1)) +``` + +For each feature, this method calculates: +- Sum of feature values across terms +- Product of feature values across terms +- A ratio metric: product/(sum+1) measuring feature consistency + +### Score Calculation + +The YAKE score for a multi-word term is calculated using: + +```python +self.h = prod_h / ((sum_h + 1) * tf_used) +``` + +Where: +- `prod_h`: Product of the h-scores of all terms +- `sum_h`: Sum of the h-scores of all terms +- `tf_used`: Term frequency (or average term frequency for virtual terms) + +Lower scores indicate better keyword candidates. + +## Stopword Handling + +The `ComposedWord` class handles stopwords differently based on the `STOPWORD_WEIGHT` configuration: + +- `"bi"`: Uses bi-directional co-occurrence probabilities to weight stopwords +- `"h"`: Uses stopword h-scores directly (treats stopwords like normal words) +- `"none"`: Ignores stopwords in scoring completely + +## Complete Usage Example + +```python +from yake.data import ComposedWord +from yake.data.utils import STOPWORD_WEIGHT + +# Create a sample composed word +terms = [("n", "natural", term_obj1), ("n", "language", term_obj2)] +composed_word = ComposedWord(terms) + +# Update the candidate's score +composed_word.update_h() + +# Check if the candidate is valid +if composed_word.is_valid(): + print(f"Candidate: {composed_word.kw}") + print(f"Score: {composed_word.h:.4f}") + print(f"Size: {composed_word.size}") + print(f"Term Frequency: {composed_word.tf}") +``` + +## Dependencies + +The `ComposedWord` class relies on: + +- `numpy`: For statistical calculations +- `jellyfish`: For string similarity measurement +- Internal utility module: + - `utils`: For stopword weighting constants + +## Integration with YAKE + +`ComposedWord` works closely with the `DataCore` class: + +1. `DataCore` generates candidate `ComposedWord` instances +2. Features are built for individual terms via `build_single_terms_features()` +3. Features for multi-word terms are built via `build_mult_terms_features()` +4. Candidates are scored using the `update_h()` method +5. Lower scores indicate better keyword candidates \ No newline at end of file diff --git a/docs-site/content/docs/Documentation/data/datacore.mdx b/docs-site/content/docs/Documentation/data/datacore.mdx new file mode 100644 index 00000000..197a9c73 --- /dev/null +++ b/docs-site/content/docs/Documentation/data/datacore.mdx @@ -0,0 +1,726 @@ +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion' + +# DataCore + +The `DataCore` class is the foundation of YAKE (Yet Another Keyword Extractor), providing the core data representation for document analysis and keyword extraction. + +> **Info:** This documentation provides interactive code views for each method. Click on a function name to view its implementation. + +## Class Overview + +```python +class DataCore: + """ + Core data representation for document analysis and keyword extraction. + + This class processes text documents to identify potential keywords based on + statistical features and contextual relationships between terms. It maintains + the document's structure, processes individual terms, and generates candidate + keywords. + + Attributes: + See property accessors below for available attributes. + """ +``` + +The `DataCore` class processes text documents to identify potential keywords based on statistical features and contextual relationships. + +## Constructor + + + + + __init__(text, stopword_set, config=None) + + + ```python + def __init__(self, text, stopword_set, config=None): + """ + Initialize the data core with text and configuration. + + Args: + text (str): The input text to analyze for keyword extraction + stopword_set (set): A set of stopwords to filter out non-content words + config (dict, optional): Configuration options including: + - windows_size (int): Size of word window for co-occurrence (default: 2) + - n (int): Maximum length of keyword phrases (default: 3) + - tags_to_discard (set): POS tags to ignore (default: {"u", "d"}) + - exclude (set): Characters to exclude (default: string.punctuation) + """ + # Initialize default configuration if none provided + if config is None: + config = {} + + # Extract configuration values with appropriate defaults + windows_size = config.get("windows_size", 2) + n = config.get("n", 3) + tags_to_discard = config.get("tags_to_discard", set(["u", "d"])) + exclude = config.get("exclude", set(string.punctuation)) + + # Initialize the state dictionary containing all component data structures + self._state = { + # Configuration settings + "config": { + "exclude": exclude, # Punctuation and other characters to exclude + "tags_to_discard": tags_to_discard, # POS tags to ignore during analysis + "stopword_set": stopword_set # Set of stopwords for filtering + }, + + # Text corpus statistics + "text_stats": { + "number_of_sentences": 0, # Total count of sentences + "number_of_words": 0 # Total count of processed words + }, + + # Core data collections for analysis + "collections": { + "terms": {}, # Dictionary mapping terms to SingleWord objects + "candidates": {}, # Dictionary mapping unique keywords to ComposedWord objects + "sentences_obj": [], # Nested list of processed sentence objects + "sentences_str": [], # List of raw sentence strings + "freq_ns": {} # Frequency distribution of n-grams by length + }, + + # Graph for term co-occurrence analysis + "g": nx.DiGraph() # Directed graph where nodes are terms and edges represent co-occurrences + } + + # Initialize n-gram frequencies with zero counts for each length 1 to n + for i in range(n): + self._state["collections"]["freq_ns"][i + 1] = 0.0 + + # Process the text and build all data structures + self._build(text, windows_size, n) + ``` + + + + +**Parameters:** +- `text` (str): The input text to analyze for keyword extraction +- `stopword_set` (set): A set of stopwords to filter out non-content words +- `config` (dict, optional): Configuration options including: + - `windows_size` (int): Size of word window for co-occurrence (default: 2) + - `n` (int): Maximum length of keyword phrases (default: 3) + - `tags_to_discard` (set): POS tags to ignore (default: {"u", "d"}) + - `exclude` (set): Characters to exclude (default: string.punctuation) + +**Example:** +```python +from yake.data import DataCore +import string +from yake.stopword_remover import StopwordRemover + +# Get stopwords +stopword_remover = StopwordRemover("en") +stopword_set = stopword_remover.get_stopword_set() + +# Initialize with default configuration +data = DataCore("Sample text for analysis", stopword_set) + +# Initialize with custom configuration +config = { + "windows_size": 3, + "n": 4, + "tags_to_discard": {"u", "d", "p"}, + "exclude": set(string.punctuation) +} +data = DataCore("Sample text for analysis", stopword_set, config) +``` + +## Core Methods + + + + + _build(text, windows_size, n) + + + ```python + def _build(self, text, windows_size, n): + """ + Build the core data structures from the input text. + + This method handles the initial processing of text, including + pre-filtering, sentence segmentation, and word tokenization. + + Args: + text (str): The input text to process + windows_size (int): Size of word window for co-occurrence analysis + n (int): Maximum n-gram length to consider for keyword candidates + """ + # Pre-process text for normalization + text = pre_filter(text) + + # Split text into sentences and tokenize + self.sentences_str = tokenize_sentences(text) + self.number_of_sentences = len(self.sentences_str) + + # Initialize position counter for global word positions + pos_text = 0 + + # Create a processing context dictionary to pass fewer arguments + context = {"windows_size": windows_size, "n": n} + + # Process each sentence individually + for sentence_id, sentence in enumerate(self.sentences_str): + pos_text = self._process_sentence(sentence, sentence_id, pos_text, context) + + # Store the total number of processed words + self.number_of_words = pos_text + ``` + + + + + + _process_sentence(sentence, sentence_id, pos_text, context) + + + ```python + def _process_sentence(self, sentence, sentence_id, pos_text, context): + """ + Process a single sentence from the document. + + Handles the tokenization of a sentence, identifies words and punctuation, + and processes each meaningful word. + + Args: + sentence (list): List of word tokens in the sentence + sentence_id (int): Unique identifier for this sentence + pos_text (int): Current global position in the text + context (dict): Processing context with configuration parameters + + Returns: + int: Updated global position counter + """ + # Initialize lists to store processed sentence components + sentence_obj_aux = [] # Blocks of words within the sentence + block_of_word_obj = [] # Current block of continuous words (separated by punctuation) + + # Extend the context with sentence information for word processing + processing_context = context.copy() + processing_context["sentence_id"] = sentence_id + + # Process each word in the sentence + for pos_sent, word in enumerate(sentence): + # Check if the word is just punctuation (all characters are excluded) + if len([c for c in word if c in self.exclude]) == len(word): + # If we have a block of words, save it and start a new block + if len(block_of_word_obj) > 0: + sentence_obj_aux.append(block_of_word_obj) + block_of_word_obj = [] + else: + # Process meaningful words + word_context = { + "pos_sent": pos_sent, # Position within the sentence + "block_of_word_obj": block_of_word_obj, # Current word block + } + # Process this word and update position counter + pos_text = self._process_word( + word, pos_text, processing_context, word_context + ) + + # Save any remaining word block + if len(block_of_word_obj) > 0: + sentence_obj_aux.append(block_of_word_obj) + + # Add processed sentence to collection if not empty + if len(sentence_obj_aux) > 0: + self.sentences_obj.append(sentence_obj_aux) + + return pos_text + ``` + + + + + + _process_word(word, pos_text, context, word_context) + + + ```python + def _process_word(self, word, pos_text, context, word_context): + """ + Process a single word within a sentence. + + Creates or retrieves the term object, updates its occurrences, + analyzes co-occurrences with nearby words, and generates candidate keywords. + + Args: + word (str): The word to process + pos_text (int): Current global position in the text + context (dict): Processing context with configuration parameters + word_context (dict): Word-specific context information + + Returns: + int: Updated global position counter + """ + # Extract necessary context variables + sentence_id = context["sentence_id"] + windows_size = context["windows_size"] + n = context["n"] + pos_sent = word_context["pos_sent"] + block_of_word_obj = word_context["block_of_word_obj"] + + # Get the part-of-speech tag for this word + tag = self.get_tag(word, pos_sent) + + # Get or create the term object for this word + term_obj = self.get_term(word) + + # Add this occurrence to the term's record + term_obj.add_occur(tag, sentence_id, pos_sent, pos_text) + + # Increment global position counter + pos_text += 1 + + # Update co-occurrence information for valid tags + if tag not in self.tags_to_discard: + self._update_cooccurrence(block_of_word_obj, term_obj, windows_size) + + # Generate keyword candidates involving this term + self._generate_candidates((tag, word), term_obj, block_of_word_obj, n) + + # Add this word to the current block + block_of_word_obj.append((tag, word, term_obj)) + + return pos_text + ``` + + + + + + _update_cooccurrence(block_of_word_obj, term_obj, windows_size) + + + ```python + def _update_cooccurrence(self, block_of_word_obj, term_obj, windows_size): + """ + Update co-occurrence information between terms. + + Records relationships between the current term and previous terms + within the specified window size. + + Args: + block_of_word_obj (list): Current block of words + term_obj (SingleWord): Term object for the current word + windows_size (int): Size of co-occurrence window to consider + """ + # Calculate the window of previous words to consider for co-occurrence + word_windows = list( + range(max(0, len(block_of_word_obj) - windows_size), len(block_of_word_obj)) + ) + + # For each word in the window, update co-occurrence if it's a valid term + for w in word_windows: + if block_of_word_obj[w][0] not in self.tags_to_discard: + # Add co-occurrence edge from previous term to current term + self.add_cooccur(block_of_word_obj[w][2], term_obj) + ``` + + + + + + _generate_candidates(term, term_obj, block_of_word_obj, n) + + + ```python + def _generate_candidates(self, term, term_obj, block_of_word_obj, n): + """ + Generate keyword candidates from terms. + + Creates single-term candidates and multi-term candidates up to length n, + combining the current term with previous terms. + + Args: + term (tuple): Current term as (tag, word) tuple + term_obj (SingleWord): Term object for the current word + block_of_word_obj (list): Current block of words + n (int): Maximum candidate length to generate + """ + # Create single-term candidate + candidate = [term + (term_obj,)] + cand = ComposedWord(candidate) + self.add_or_update_composedword(cand) + + # Calculate window of previous words to consider for multi-term candidates + word_windows = list( + range(max(0, len(block_of_word_obj) - (n - 1)), len(block_of_word_obj)) + )[::-1] # Reverse to build phrases from right to left + + # Generate multi-term candidates with increasing length + for w in word_windows: + # Add previous term to candidate + candidate.append(block_of_word_obj[w]) + + # Update frequency count for this n-gram length + self.freq_ns[len(candidate)] += 1.0 + + # Create and register the composed word candidate + # (reverse to maintain correct word order) + cand = ComposedWord(candidate[::-1]) + self.add_or_update_composedword(cand) + ``` + + + + +## Public API Methods + + + + + get_tag(word, i) + + + ```python + def get_tag(self, word, i): + """ + Get the part-of-speech tag for a word. + + Args: + word (str): The word to tag + i (int): Position of the word in its sentence + + Returns: + str: Single character tag representing the word type + ("d" for digit, "u" for unusual, "a" for acronym, + "n" for proper noun, "p" for plain word) + """ + return get_tag(word, i, self.exclude) + ``` + + + + + + build_candidate(candidate_string) + + + ```python + def build_candidate(self, candidate_string): + """ + Build a candidate ComposedWord from a string. + + This function processes a candidate string by tokenizing it, tagging each word, + and creating a ComposedWord object from the resulting terms. It's used to + convert external strings into the internal candidate representation. + + Args: + candidate_string (str): String to convert to a keyword candidate + + Returns: + ComposedWord: A composed word object representing the candidate + """ + + # Tokenize the candidate string + tokenized_words = [ + w + for w in split_contractions(web_tokenizer(candidate_string.lower())) + if not (w.startswith("'") and len(w) > 1) and len(w) > 0 + ] + + # Process each word in the candidate + candidate_terms = [] + for index, word in enumerate(tokenized_words): + # Get the tag and term object + tag = self.get_tag(word, index) + term_obj = self.get_term(word, save_non_seen=False) + + # Skip terms with zero term frequency (not in the original document) + if term_obj.tf == 0: + term_obj = None + + candidate_terms.append((tag, word, term_obj)) + + # Check if the candidate has any valid terms + if not any(term[2] for term in candidate_terms): + # Return an invalid composed word if no valid terms + return ComposedWord(None) + + # Create and return the composed word + return ComposedWord(candidate_terms) + ``` + + + + + + build_single_terms_features(features=None) + + + ```python + def build_single_terms_features(self, features=None): + """ + Calculates and updates statistical features for all single terms in the text. + This includes term frequency statistics and other features specified in the + features parameter. Only non-stopword terms are considered for statistics + calculation. + + Args: + features (list, optional): Specific features to calculate + """ + # Filter to valid terms (non-stopwords) + valid_terms = [term for term in self.terms.values() if not term.stopword] + valid_tfs = np.array([x.tf for x in valid_terms]) + + # Skip if no valid terms + if len(valid_tfs) == 0: + return + + # Calculate frequency statistics + avg_tf = valid_tfs.mean() + std_tf = valid_tfs.std() + max_tf = max(x.tf for x in self.terms.values()) + + # Prepare statistics dictionary for updating terms + stats = { + "max_tf": max_tf, + "avg_tf": avg_tf, + "std_tf": std_tf, + "number_of_sentences": self.number_of_sentences, + } + + # Update all terms with the calculated statistics + list(map(lambda x: x.update_h(stats, features=features), self.terms.values())) + ``` + + + + + + build_mult_terms_features(features=None) + + + ```python + def build_mult_terms_features(self, features=None): + """ + Build features for multi-word terms. + + Updates the features for all valid multi-word candidate terms (n-grams). + Only candidates that pass the validity check will have their features updated. + + Args: + features (list, optional): List of features to build. If None, all available features will be built. + """ + # Update only valid candidates (filter then apply update_h) + list( + map( + lambda x: x.update_h(features=features), + [cand for cand in self.candidates.values() if cand.is_valid()], + ) + ) + ``` + + + + + + get_term(str_word, save_non_seen=True) + + + ```python + def get_term(self, str_word, save_non_seen=True): + """ + Get or create a term object for a word. + + Handles word normalization, stopword checking, and term object creation. + + Args: + str_word (str): The word to get a term object for + save_non_seen (bool, optional): Whether to save new terms to the collection + + Returns: + SingleWord: Term object representing this word + """ + # Normalize the term (convert to lowercase) + unique_term = str_word.lower() + + # Check if it's a stopword in original form + simples_sto = unique_term in self.stopword_set + + # Handle plural forms by removing trailing 's' + if unique_term.endswith("s") and len(unique_term) > 3: + unique_term = unique_term[:-1] + + # Return existing term if already processed + if unique_term in self.terms: + return self.terms[unique_term] + + # Remove punctuation for further analysis + simples_unique_term = unique_term + for pontuation in self.exclude: + simples_unique_term = simples_unique_term.replace(pontuation, "") + + # Determine if this is a stopword (original form, normalized form, or too short) + isstopword = ( + simples_sto + or unique_term in self.stopword_set + or len(simples_unique_term) < 3 + ) + + # Create the term object + term_id = len(self.terms) + term_obj = SingleWord(unique_term, term_id, self.g) + term_obj.stopword = isstopword + + # Save the term to the collection if requested + if save_non_seen: + self.g.add_node(term_id) + self.terms[unique_term] = term_obj + + return term_obj + ``` + + + + + + add_cooccur(left_term, right_term) + + + ```python + def add_cooccur(self, left_term, right_term): + """ + Add a co-occurrence relationship between two terms. + + Updates the co-occurrence graph by adding or incrementing an edge between + two terms. This information is used to calculate term relatedness and + importance in the text. + + Args: + left_term (SingleWord): Source term in the relationship + right_term (SingleWord): Target term in the relationship + """ + # Check if the edge already exists + if right_term.id not in self.g[left_term.id]: + # Create a new edge with initial weight + self.g.add_edge(left_term.id, right_term.id, tf=0.0) + + # Increment the co-occurrence frequency + self.g[left_term.id][right_term.id]["tf"] += 1.0 + ``` + + + + + + add_or_update_composedword(cand) + + + ```python + def add_or_update_composedword(self, cand): + """ + Add or update a composed word in the candidates collection. + + Adds a new candidate composed word (n-gram) to the candidates dictionary + or updates an existing one by incrementing its frequency. This is used to + track potential keyphrases in the text. + + Args: + cand (ComposedWord): ComposedWord instance to add or update in the candidates dictionary + """ + # Check if this candidate already exists + if cand.unique_kw not in self.candidates: + # Add new candidate + self.candidates[cand.unique_kw] = cand + else: + # Update existing candidate with new information + self.candidates[cand.unique_kw].uptade_cand(cand) + + # Increment the frequency counter for this candidate + self.candidates[cand.unique_kw].tf += 1.0 + ``` + + + + +## Property Accessors + +The `DataCore` class includes various property accessors for backward compatibility: + +### Configuration Properties + +- `exclude`: Characters to exclude from processing +- `tags_to_discard`: Part-of-speech tags to ignore during analysis +- `stopword_set`: Set of stopwords to filter out +- `g`: DirectedGraph representing term co-occurrences + +```python +# Examples +excluded_chars = data.exclude +ignored_tags = data.tags_to_discard +stopwords = data.stopword_set +graph = data.g +``` + +### Text Statistics Properties + +- `number_of_sentences`: Count of sentences in the processed text +- `number_of_words`: Total number of words processed + +```python +# Examples +sentence_count = data.number_of_sentences +word_count = data.number_of_words +``` + +### Collection Properties + +- `terms`: Dictionary of `SingleWord` objects representing individual terms +- `candidates`: Dictionary of `ComposedWord` objects representing keyword candidates +- `sentences_obj`: Processed sentence objects +- `sentences_str`: Raw sentence strings from the original text +- `freq_ns`: Frequency of n-grams by length + +```python +# Examples +all_terms = data.terms +all_candidates = data.candidates +processed_sentences = data.sentences_obj +raw_sentences = data.sentences_str +ngram_frequencies = data.freq_ns +``` + +## Complete Usage Example + +```python +from yake.data import DataCore +from yake.stopword_remover import StopwordRemover + +# Initialize stopwords +stopword_remover = StopwordRemover("en") +stopword_set = stopword_remover.get_stopword_set() + +# Create DataCore instance +text = "Natural language processing is a field of artificial intelligence that focuses on the interaction between computers and humans using natural language." +data = DataCore(text, stopword_set) + +# Build features for keyword extraction +data.build_single_terms_features() +data.build_mult_terms_features() + +# Extract top candidates +candidates = [(cand.unique_kw, cand.h) for cand in data.candidates.values() if cand.is_valid()] +candidates.sort(key=lambda x: x[1]) # Sort by score (lower is better in YAKE) + +# Print top 5 keywords +for keyword, score in candidates[:5]: + print(f"{keyword}: {score:.4f}") +``` + +## Dependencies + +The `DataCore` class relies on: + +- `string`: For punctuation constants +- `networkx`: For graph representation (co-occurrences) +- `numpy`: For statistical calculations +- `segtok`: For tokenization +- Internal utility modules: + - `utils`: For pre-filtering and tokenization + - `single_word`: For representing individual terms + - `composed_word`: For representing multi-word candidates \ No newline at end of file diff --git a/docs-site/content/docs/Documentation/data/singleword.mdx b/docs-site/content/docs/Documentation/data/singleword.mdx new file mode 100644 index 00000000..79d74cf3 --- /dev/null +++ b/docs-site/content/docs/Documentation/data/singleword.mdx @@ -0,0 +1,521 @@ +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion' + +# SingleWord + +The `SingleWord` class represents individual terms in YAKE (Yet Another Keyword Extractor), providing the statistical features and measurements used in keyword extraction. + +> **Info:** This documentation provides interactive code views for each method. Click on a function name to view its implementation. + +## Module Overview + +```python +""" +Single word term representation module for YAKE keyword extraction. + +This module contains the SingleWord class which represents individual terms +in a document for keyword extraction. It tracks statistical features like +term frequency, position, and relationships with other terms to calculate +a relevance score for each word. +""" + +import math +import numpy as np +``` + +The `SingleWord` class stores and calculates statistical features for individual terms, including frequency, position, spread, and relationship metrics. These features are used to calculate a relevance score that indicates the word's importance in the document. + +## Constructor + + + + + __init__(unique, idx, graph) + + + ```python + def __init__(self, unique, idx, graph): + """ + Initialize a SingleWord term object. + + Args: + unique (str): The unique normalized term this object represents + idx (int): Unique identifier for the term in the document + graph (networkx.DiGraph): Word co-occurrence graph from the document + """ + self.id = idx # Fast access needed as it's used in graph operations + self.g = graph # Fast access needed for network calculations + + self.data = { + # Basic information + "unique_term": unique, + "stopword": False, + "h": 0.0, # Final Score + # Term frequency statistics + "tf": 0.0, # Term frequency + "tf_a": 0.0, # Term Frequency for uppercase words + "tf_n": 0.0, # Term Frequency for proper nouns + # Word characteristic metrics + "wfreq": 0.0, # Word frequency + "wcase": 0.0, # Word case metric + "wrel": 1.0, # Word relevance metric + "wpos": 1.0, # Word position metric + "wspread": 0.0, # Word spread across document + "pl": 0.0, # Probability left + "pr": 0.0, # Probability right + "pagerank": 1.0, # PageRank score + # Ocurrence tracking + "occurs": {}, # Sentence Occurrences + } + ``` + + + + +**Parameters:** +- `unique` (str): The unique normalized term this object represents +- `idx` (int): Unique identifier for the term in the document +- `graph` (networkx.DiGraph): Word co-occurrence graph from the document + +**Example:** +```python +import networkx as nx +from yake.data import SingleWord + +# Create a graph +g = nx.DiGraph() + +# Initialize a single word +term = SingleWord("algorithm", 1, g) +``` + +## Dictionary-Style Access + +The `SingleWord` class provides dictionary-style attribute access for flexibility: + + + + + __getitem__(key) + + + ```python + def __getitem__(self, key): + """ + Access attributes dictionary-style with obj['key']. + + Args: + key (str): The attribute key to access + + Returns: + Any: The value associated with the key + """ + return self.data[key] + ``` + + + + + + __setitem__(key, value) + + + ```python + def __setitem__(self, key, value): + """ + Set attributes dictionary-style with obj['key'] = value. + + Args: + key (str): The attribute key to set + value (Any): The value to associate with the key + """ + self.data[key] = value + ``` + + + + + + get(key, default=None) + + + ```python + def get(self, key, default=None): + """ + Get with default, mimicking dict.get(). + + Args: + key (str): The attribute key to access + default (Any, optional): The default value if key doesn't exist + + Returns: + Any: The value associated with the key or the default value + """ + return self.data.get(key, default) + ``` + + + + +**Example:** +```python +# Dictionary-style access +term["wfreq"] = 2.5 +score = term["h"] +position = term.get("wpos", 1.0) +``` + +## Core Methods + + + + + add_occur(tag, sent_id, pos_sent, pos_text) + + + ```python + def add_occur(self, tag, sent_id, pos_sent, pos_text): + """ + Add occurrence information for this term. + + Records where in the document this term appears, tracking sentence ID, + position within sentence, global position in text, and updates term + frequency counters. + + Args: + tag (str): Part-of-speech tag for this occurrence ('a' for acronym, 'n' for proper noun, etc.) + sent_id (int): Sentence ID where the term appears + pos_sent (int): Position within the sentence + pos_text (int): Global position in the entire text + """ + # Create empty list for this sentence if it's the first occurrence + if sent_id not in self.occurs: + self.occurs[sent_id] = [] + + # Record position information for this occurrence + self.occurs[sent_id].append((pos_sent, pos_text)) + self.data["tf"] += 1.0 + + # Update special counters for acronyms and proper nouns + if tag == "a": + self.data["tf_a"] += 1.0 + if tag == "n": + self.data["tf_n"] += 1.0 + ``` + + + + + + get_metric(name) + + + ```python + def get_metric(self, name): + """ + Get the value of any word metric. + + Args: + name (str): The name of the metric to retrieve + + Returns: + float: The value of the requested metric + """ + return self.data.get(name, 0.0) + ``` + + + + + + set_metric(name, value) + + + ```python + def set_metric(self, name, value): + """ + Set the value of any word metric. + + Args: + name (str): The name of the metric to set + value (float): The new value for the metric + """ + self.data[name] = value + ``` + + + + + + get_graph_metrics() + + + ```python + def get_graph_metrics(self): + """ + Calculate all graph-based metrics at once. + + Analyzes the term's connections in the co-occurrence graph to compute + various relationship metrics that measure its contextual importance. + + Returns: + dict: Dictionary containing the calculated graph metrics: + - wdr: Word different right (number of outgoing edges) + - wir: Word importance right (sum of outgoing edge weights) + - pwr: Probability weight right (wdr/wir) + - wdl: Word different left (number of incoming edges) + - wil: Word importance left (sum of incoming edge weights) + - pwl: Probability weight left (wdl/wil) + """ + # Out-edges metrics + wdr = len(self.g.out_edges(self.id)) + wir = sum(d["tf"] for (_, _, d) in self.g.out_edges(self.id, data=True)) + pwr = 0 if wir == 0 else wdr / wir + + # In-edges metrics + wdl = len(self.g.in_edges(self.id)) + wil = sum(d["tf"] for (_, _, d) in self.g.in_edges(self.id, data=True)) + pwl = 0 if wil == 0 else wdl / wil + + return {"wdr": wdr, "wir": wir, "pwr": pwr, "wdl": wdl, "wil": wil, "pwl": pwl} + ``` + + + + + + update_h(stats, features=None) + + + ```python + def update_h(self, stats, features=None): + """ + Update the word's score based on statistics. + + Calculates all the statistical features that determine the word's + relevance score, using document-level statistics for normalization. + + Args: + stats (dict): Document statistics including: + - max_tf (float): Maximum term frequency in the document + - avg_tf (float): Average term frequency + - std_tf (float): Standard deviation of term frequency + - number_of_sentences (int): Total number of sentences + features (list, optional): Specific features to calculate, or None for all + """ + max_tf = stats["max_tf"] + avg_tf = stats["avg_tf"] + std_tf = stats["std_tf"] + number_of_sentences = stats["number_of_sentences"] + + # Get all graph metrics at once + graph_metrics = self.get_graph_metrics() + + # Update metrics based on features + if features is None or "wrel" in features: + # Calculate relatedness metrics using graph connections + self.data["pl"] = graph_metrics["wdl"] / max_tf + self.data["pr"] = graph_metrics["wdr"] / max_tf + self.data["wrel"] = (0.5 + (graph_metrics["pwl"] * (self.tf / max_tf))) + ( + 0.5 + (graph_metrics["pwr"] * (self.tf / max_tf)) + ) + + if features is None or "wfreq" in features: + # Calculate frequency metric normalized by corpus statistics + self.data["wfreq"] = self.tf / (avg_tf + std_tf) + + if features is None or "wspread" in features: + # Calculate spread as proportion of sentences containing the term + self.data["wspread"] = len(self.occurs) / number_of_sentences + + if features is None or "wcase" in features: + # Calculate case feature from uppercase and proper noun occurrences + self.data["wcase"] = max(self.data["tf_a"], self.data["tf_n"]) / ( + 1.0 + math.log(self.tf) + ) + + if features is None or "wpos" in features: + # Calculate position feature from median position of occurrences + self.data["wpos"] = math.log( + math.log(3.0 + np.median(list(self.occurs.keys()))) + ) + + # Calculate final score + self.data["h"] = (self.data["wpos"] * self.data["wrel"]) / ( + self.data["wcase"] + + (self.data["wfreq"] / self.data["wrel"]) + + (self.data["wspread"] / self.data["wrel"]) + ) + ``` + + + + +## Properties + +The `SingleWord` class provides property accessors for its main attributes: + +### Basic Properties + +- `unique_term`: The normalized form of the word +- `stopword`: Boolean indicating if the term is a stopword +- `h`: The final score of the term (lower is better in YAKE) +- `tf`: Term frequency in the document +- `occurs`: Dictionary of sentence occurrences + +```python +# Examples +word = term.unique_term +is_stopword = term.stopword +score = term.h +frequency = term.tf +occurrences = term.occurs + +# Setter examples +term.stopword = True +term.h = 0.25 +term.tf = 5.0 +``` + +### Feature Properties + +- `wfreq`: Word frequency metric +- `wcase`: Word case metric (uppercase/proper noun) +- `wrel`: Word relevance metric (based on graph connections) +- `wpos`: Word position metric +- `wspread`: Word spread across document +- `pl`: Probability left (graph-based) +- `pr`: Probability right (graph-based) + +```python +# Examples +frequency_metric = term.wfreq +case_metric = term.wcase +relevance = term.wrel +position_metric = term.wpos +spread_metric = term.wspread +left_probability = term.pl +right_probability = term.pr + +# Setter examples +term.wfreq = 0.75 +term.wcase = 0.5 +term.wrel = 1.2 +``` + +## Feature Calculation Logic + +The `SingleWord` class calculates several features that contribute to keyword scoring: + +### Word Frequency (`wfreq`) + +Measures how frequent the term is compared to the average document term frequency. + +```python +# Normalized term frequency compared to document statistics +wfreq = term_frequency / (average_term_frequency + standard_deviation) +``` + +Higher values indicate more frequent terms relative to the document average. + +### Word Case (`wcase`) + +Represents the significance of capitalization in determining proper nouns and acronyms. + +```python +# Case significance: higher values for acronyms and proper nouns +wcase = max(uppercase_freq, proper_noun_freq) / (1.0 + log(term_frequency)) +``` + +Higher values indicate terms more likely to be acronyms or proper nouns. + +### Word Relevance (`wrel`) + +Evaluates the term's importance based on its co-occurrence relationships. + +```python +# Relevance based on graph connection probabilities and term frequency +wrel = (0.5 + (graph_metrics["pwl"] * (tf / max_tf))) + + (0.5 + (graph_metrics["pwr"] * (tf / max_tf))) +``` + +Higher values indicate terms with more meaningful contextual relationships. + +### Word Position (`wpos`) + +Considers the typical position of the word in sentences, with the intuition that important terms appear earlier. + +```python +# Position score based on median sentence position +wpos = math.log(math.log(3.0 + median_position_in_sentences)) +``` + +Lower values indicate terms that tend to appear earlier in sentences. + +### Word Spread (`wspread`) + +Measures how widely the term is distributed across the document's sentences. + +```python +# Document coverage: proportion of sentences containing the term +wspread = number_of_sentences_with_term / total_number_of_sentences +``` + +Higher values indicate terms that appear throughout the document. + +## Final Score Calculation + +The final score (`h`) combines all metrics in a formula designed to rank candidate keywords: + +```python +# Lower scores indicate better keyword candidates +h = (wpos * wrel) / (wcase + (wfreq / wrel) + (wspread / wrel)) +``` + +The formula balances: +- Term position (earlier is better) +- Term relevance (more connections is better) +- Term case (proper nouns and acronyms preferred) +- Term frequency (higher is better) +- Term spread (wider distribution is better) + +Lower scores indicate better keyword candidates in YAKE's ranking system. + +## Usage Example + +```python +import networkx as nx +import numpy as np +from yake.data import SingleWord + +# Create a graph for co-occurrence +g = nx.DiGraph() +g.add_node(1) + +# Initialize a word +term = SingleWord("algorithm", 1, g) + +# Add occurrences +term.add_occur("n", 0, 5, 5) # In sentence 0, position 5 +term.add_occur("n", 1, 2, 15) # In sentence 1, position 2 +term.add_occur("n", 2, 8, 35) # In sentence 2, position 8 + +# Update the score with statistics +stats = { + "max_tf": 10.0, + "avg_tf": 3.0, + "std_tf": 2.0, + "number_of_sentences": 5 +} +term.update_h(stats) + +# Get the final score +print(f"Keyword score for 'algorithm': {term.h:.4f}") +``` + +## Dependencies + +The `SingleWord` class relies on: + +- `math`: For logarithmic calculations +- `numpy`: For statistical operations (median) +- `networkx`: Implicitly through the provided graph parameter \ No newline at end of file diff --git a/docs-site/content/docs/Documentation/data/utils.mdx b/docs-site/content/docs/Documentation/data/utils.mdx new file mode 100644 index 00000000..8077eca2 --- /dev/null +++ b/docs-site/content/docs/Documentation/data/utils.mdx @@ -0,0 +1,294 @@ +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion' + +# Utils + +The `utils` module provides essential text processing functions for YAKE (Yet Another Keyword Extractor), handling tokenization, normalization, and classification of textual elements. + +> **Info:** This documentation provides interactive code views for each function. Click on a function name to view its implementation. + +## Module Overview + +```python +""" +Text processing utility module for YAKE keyword extraction. + +This module provides essential text preprocessing functions for the YAKE algorithm, +including text normalization, sentence segmentation, tokenization, and word +categorization. These utilities form the foundation for clean and consistent +text analysis throughout the keyword extraction pipeline. +""" + +import re +from segtok.segmenter import split_multi +from segtok.tokenizer import web_tokenizer, split_contractions + +# Stopword weighting method for multi-word term scoring: +# - "bi": Use bi-directional weighting (default, considers term connections) +# - "h": Use direct term scores (treat stopwords like normal words) +# - "none": Ignore stopwords completely +STOPWORD_WEIGHT = "bi" +``` + +The `utils` module contains functions for text preprocessing, tokenization, and classification that support the keyword extraction pipeline. + +## Functions + + + + + pre_filter(text) + + + ```python + def pre_filter(text): + """Pre-filter text before processing. + + This function prepares raw text for keyword extraction by normalizing its format. + It performs several transformations: + + 1. Splits the text into parts based on newline characters + 2. Detects if a part starts with a capital letter (potentially a new paragraph) + 3. Adds appropriate spacing between parts: + - Double newlines for parts starting with capital letters (likely new paragraphs) + - Single spaces for other parts (likely continuing text) + 4. Replaces all tab characters with spaces for consistent formatting + + This preprocessing helps maintain paragraph structure while normalizing + whitespace, which improves the accuracy of subsequent text analysis steps + like sentence boundary detection and keyword extraction. + + Args: + text: Raw input text to be pre-filtered + + Returns: + Normalized text with consistent spacing and paragraph structure + """ + # Regular expression to detect lines starting with capital letters + prog = re.compile("^(\\s*([A-Z]))") + + # Split the text into lines + parts = text.split("\n") + buffer = "" + + # Process each line + for part in parts: + # Determine separator: preserve paragraph breaks for lines starting with capital letters + sep = " " + if prog.match(part): + sep = "\n\n" + + # Append the processed line to the buffer, replacing tabs with spaces + buffer += sep + part.replace("\t", " ") + + return buffer + ``` + + + + + + tokenize_sentences(text) + + + ```python + def tokenize_sentences(text): + """ + Split text into sentences and tokenize into words. + + This function performs two-level tokenization: first dividing the text into + sentences using segtok's sentence segmenter, then tokenizing each sentence + into individual words. It also handles contractions and filters out empty + or invalid tokens. + + Args: + text (str): The input text to be tokenized + + Returns: + list: A nested list structure where each inner list contains the tokens + for a single sentence in the original text + """ + return [ + # Inner list: tokenize each sentence into words + [ + w # Keep only valid word tokens + for w in split_contractions(web_tokenizer(s)) + # Filter out standalone apostrophes and empty tokens + if not (w.startswith("'") and len(w) > 1) and len(w) > 0 + ] + # Outer list: iterate through sentences + for s in list(split_multi(text)) + # Skip empty sentences + if len(s.strip()) > 0 + ] + ``` + + + + + + get_tag(word, i, exclude) + + + ```python + def get_tag(word, i, exclude): + """ + Determine the linguistic tag of a word based on its characteristics. + + This function categorizes words into different types based on their + orthographic features (capitalization, digits, special characters). + These tags are used to identify proper nouns, acronyms, numbers, and + unusual token patterns, which affect keyword scoring and filtering. + + Args: + word (str): The word to classify + i (int): Position of the word within its sentence (0 = first word) + exclude (set): Set of characters to consider as punctuation/special chars + + Returns: + str: A single character tag representing the word type: + - "d": Digit or numeric value + - "u": Unusual word (mixed alphanumeric or special characters) + - "a": Acronym (all uppercase) + - "n": Proper noun (capitalized, not at start of sentence) + - "p": Plain word (default) + """ + # Check if word is numeric (with possible commas and a decimal point) + if word.replace(",", "").isdigit() or word.replace(",", "").replace(".", "", 1).isdigit(): + return "d" + + # Count character types for classification + cdigit = sum(c.isdigit() for c in word) + calpha = sum(c.isalpha() for c in word) + cexclude = sum(c in exclude for c in word) + + # Classify unusual tokens: mixed alphanumeric, special chars, or multiple punctuation + if (cdigit > 0 and calpha > 0) or (cdigit == 0 and calpha == 0) or cexclude > 1: + return "u" + + # Identify acronyms (all uppercase words) + if word.isupper() and len(word) > 0: + return "a" + + # Identify proper nouns (capitalized words not at sentence beginning) + if len(word) > 1 and word[0].isupper() and i > 0: + # Check that only the first letter is uppercase (not an all-caps word) + if sum(c.isupper() for c in word) == 1: + return "n" + + # Default case: plain word + return "p" + ``` + + + + +## Function Descriptions + +### pre_filter + +Pre-filters text before processing by normalizing its format. It maintains paragraph structure while standardizing spacing and line breaks to improve the accuracy of subsequent text analysis steps. + +**Parameters:** +- `text` (str): Raw input text to be pre-filtered + +**Returns:** +- str: Normalized text with consistent spacing and paragraph structure + +**How it works:** +1. Splits the text into parts based on newline characters +2. Detects if a part starts with a capital letter (potentially a new paragraph) +3. Adds appropriate spacing between parts: + - Double newlines for parts starting with capital letters (likely new paragraphs) + - Single spaces for other parts (likely continuing text) +4. Replaces all tab characters with spaces for consistent formatting + +**Example:** +```python +from yake.data.utils import pre_filter + +raw_text = "This is line one.\nThis is line two.\tAnd this has a tab." +normalized_text = pre_filter(raw_text) +print(normalized_text) +# Output: " This is line one. This is line two. And this has a tab." + +raw_text = "This is line one.\nAnother paragraph.\nThis continues." +normalized_text = pre_filter(raw_text) +print(normalized_text) +# Output: " This is line one.\n\nAnother paragraph. This continues." +``` + +### tokenize_sentences + +Performs two-level tokenization: first dividing the text into sentences, then tokenizing each sentence into words while handling contractions and filtering out invalid tokens. + +**Parameters:** +- `text` (str): The input text to tokenize + +**Returns:** +- list: A nested list where each inner list contains the tokens of a sentence + +**Example:** +```python +from yake.utils import tokenize_sentences + +text = "Hello world! This is a sample text. It has multiple sentences." +sentences = tokenize_sentences(text) +print(sentences) +# Output: [['Hello', 'world', '!'], ['This', 'is', 'a', 'sample', 'text', '.'], ['It', 'has', 'multiple', 'sentences', '.']] +``` + +### get_tag + +Categorizes words into different types based on their orthographic features (capitalization, digits, special characters), which affect keyword scoring and filtering. + +**Parameters:** +- `word` (str): The word to classify +- `i` (int): Position of the word within its sentence (0 = first word) +- `exclude` (set): Set of characters to consider as punctuation/special chars + +**Returns:** +- str: A single character tag representing the word type: + - `"d"`: Digit or numeric value + - `"u"`: Unusual word (mixed alphanumeric or special characters) + - `"a"`: Acronym (all uppercase) + - `"n"`: Proper noun (capitalized, not at start of sentence) + - `"p"`: Plain word (default) + +**Example:** +```python +from yake.utils import get_tag +import string + +exclude = set(string.punctuation) + +# Examples of different word classifications +print(get_tag("Hello", 0, exclude)) # Output: "p" (plain word) +print(get_tag("Hello", 3, exclude)) # Output: "n" (proper noun, capitalized not at sentence start) +print(get_tag("123", 0, exclude)) # Output: "d" (digit) +print(get_tag("NASA", 0, exclude)) # Output: "a" (acronym) +print(get_tag("test@example", 0, exclude)) # Output: "u" (unusual) +``` + +## Module Constants + +- `STOPWORD_WEIGHT` (str): Stopword weighting method for multi-word term scoring: + - `"bi"`: Use bi-directional weighting (default, considers term connections) + - `"h"`: Use direct term scores (treat stopwords like normal words) + - `"none"`: Ignore stopwords completely + +## Usage in YAKE Pipeline + +The utility functions serve as foundation components for the YAKE keyword extraction process: + +1. `pre_filter` normalizes the input text +2. `tokenize_sentences` breaks the text into processable tokens +3. `get_tag` classifies each token for further analysis + +These functions are primarily used by the `DataCore` class to build the data representation needed for keyword extraction. + +## Dependencies + +The utils module relies on: +- `re`: For regular expression operations +- `segtok.segmenter`: For sentence segmentation +- `segtok.tokenizer`: For tokenization and contraction handling \ No newline at end of file diff --git a/docs-site/content/docs/_meta.json b/docs-site/content/docs/_meta.json new file mode 100644 index 00000000..13f6c56c --- /dev/null +++ b/docs-site/content/docs/_meta.json @@ -0,0 +1,24 @@ +{ + "home": { + "title": "Home" + }, + "getting-started": { + "title": "Getting Started" + }, + "related-projects": { + "title": "Related Projects" + }, + "about": { + "title": "About" + }, + "--": { + "title": "Documentation", + "type": "separator" + }, + "core": { + "title": "Core" + }, + "data": { + "title": "Data" + } +} \ No newline at end of file diff --git a/docs-site/content/docs/about.mdx b/docs-site/content/docs/about.mdx new file mode 100644 index 00000000..17e6cb75 --- /dev/null +++ b/docs-site/content/docs/about.mdx @@ -0,0 +1,36 @@ +--- +title: About +icon: CircleHelp +--- + +This project was developed by LIAAD - Laboratory of Artificial Intelligence and Decision Support. LIAAD is an R&D laboratory at [INESCTEC](http://www.inesctec.pt/en). It is one of the associated units of INESC Tec which is funded by Fundação para a Ciência e a Tecnologia (FCT, Portugal). + +--- + +## Authors + +* **Ricardo Campos** is an assistant professor at the ICT Departmental Unit of the Polytechnic Institute of Tomar (IPT) and member of LIAAD-INESC TEC, the Artificial Intelligence and Decision Support Lab of U. Porto. He is PhD in Computer Science by the University of Porto (U. Porto). + +* **Vítor Mangaravite** is a research intern of LIAAD/INESC TEC - INESC Technology. He has MSc and BSc in Computer Science by Universidade Federal de Minas Gerais and Universidade Federal de Ouro Preto, respectively. + +* **Arian Pasquali** is a researcher associated to University of Porto and the Artificial Intelligence and Decision Support Laboratory at INESC TEC - INESC Technology. He has MSc in Computer Science by University of Porto with specialization in data mining. + +* **Alípio M. Jorge** is an associate professor at the Department of Computer Science of the Faculty of Science of the U. Porto and the coordinator of LIAAD/INESC TEC - INESC Technology and Science, the Artificial Intelligence and Decision Support Lab of U. Porto since 2012. He is PhD in Computer Science by U. Porto. + +* **Célia Nunes** is an Assistant Professor at the Department of Mathematics of the University of Beira Interior (UBI) and member of CMA - Center of Mathematics and Aplications, UBI. She is PhD in Mathematics by UBI, MSc. on Applied Mathematics by the University of Évora (UE) and BSc. in Mathematics - Probability and Statistics (UE). + +* **Adam Jatowt** is an Associate Professor at the Department of Computer Science, University of Innsbruck. He has received his Ph.D. in Information Science and Technology from the University of Tokyo, Japan in 2005. + + +## Aknowledgements +Project "TEC4Growth - Pervasive Intelligence, Enhancers and Proofs of Concept with Industrial Impact/NORTE-01-0145-FEDER-000020" is financed by the North Portugal Regional Operational Programme (NORTE 2020), under the PORTUGAL 2020 Partnership Agreement, and through the European Regional Development Fund (ERDF). + +--- +
+

+ Back to top +

+

+ Copyright ©2018-{new Date().getFullYear()} INESC TEC. Distributed by an INESCTEC license. +

+
\ No newline at end of file diff --git a/docs-site/lib/source.ts b/docs-site/lib/source.ts new file mode 100644 index 00000000..9871c2fc --- /dev/null +++ b/docs-site/lib/source.ts @@ -0,0 +1,11 @@ +import { docs } from '@/.source'; +import { loader } from 'fumadocs-core/source'; +import { createMDXSource } from 'fumadocs-mdx'; +import { meta } from '@/.source'; + +// See https://fumadocs.vercel.app/docs/headless/source-api for more info +export const source = loader({ + // it assigns a URL to your pages + baseUrl: '/docs', + source: createMDXSource(docs, meta), +}); diff --git a/docs-site/lib/utils.ts b/docs-site/lib/utils.ts new file mode 100644 index 00000000..bd0c391d --- /dev/null +++ b/docs-site/lib/utils.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/docs-site/mdx-components.tsx b/docs-site/mdx-components.tsx new file mode 100644 index 00000000..d3fbb13f --- /dev/null +++ b/docs-site/mdx-components.tsx @@ -0,0 +1,10 @@ +import defaultMdxComponents from 'fumadocs-ui/mdx'; +import type { MDXComponents } from 'mdx/types'; + +// use this function to get MDX components, you will need it for rendering MDX +export function getMDXComponents(components?: MDXComponents): MDXComponents { + return { + ...defaultMdxComponents, + ...components, + }; +} diff --git a/docs-site/next.config.mjs b/docs-site/next.config.mjs new file mode 100644 index 00000000..a6e5d82a --- /dev/null +++ b/docs-site/next.config.mjs @@ -0,0 +1,21 @@ +import { createMDX } from 'fumadocs-mdx/next'; + +const withMDX = createMDX(); + +const REPO_NAME = 'yakerf'; + +/** @type {import('next').NextConfig} */ +const config = { + reactStrictMode: true, + output: 'export', + // Configuração para GitHub Pages + basePath: process.env.NODE_ENV === 'production' ? `/${REPO_NAME}` : '', + assetPrefix: process.env.NODE_ENV === 'production' ? `/${REPO_NAME}/` : '', + images: { + unoptimized: true, + }, + // Desabilitar trailing slash para compatibilidade com GitHub Pages + trailingSlash: false, +}; + +export default withMDX(config); \ No newline at end of file diff --git a/docs-site/package-lock.json b/docs-site/package-lock.json new file mode 100644 index 00000000..502a5c55 --- /dev/null +++ b/docs-site/package-lock.json @@ -0,0 +1,12953 @@ +{ + "name": "docs-site", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "docs-site", + "version": "0.0.0", + "hasInstallScript": true, + "dependencies": { + "@radix-ui/react-accordion": "^1.2.8", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "fumadocs-core": "15.2.9", + "fumadocs-mdx": "11.6.1", + "fumadocs-ui": "^15.2.9", + "lucide-react": "^0.503.0", + "next": "15.3.1", + "nextra": "^1.1.0", + "react": "^19.1.0", + "react-dom": "^19.1.0", + "tailwind-merge": "^3.2.0", + "tw-animate-css": "^1.2.8" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4.1.4", + "@types/mdx": "^2.0.13", + "@types/node": "22.14.1", + "@types/react": "^19.1.2", + "@types/react-dom": "^19.1.2", + "eslint": "^8", + "eslint-config-next": "15.3.1", + "glob": "^8.1.0", + "gray-matter": "^4.0.3", + "postcss": "^8.5.3", + "tailwindcss": "^4.1.4", + "typescript": "^5.8.3" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emnapi/core": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz", + "integrity": "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==", + "dev": true, + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.0.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", + "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz", + "integrity": "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==", + "dev": true, + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.3.tgz", + "integrity": "sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.3.tgz", + "integrity": "sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.3.tgz", + "integrity": "sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.3.tgz", + "integrity": "sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.3.tgz", + "integrity": "sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.3.tgz", + "integrity": "sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.3.tgz", + "integrity": "sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.3.tgz", + "integrity": "sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.3.tgz", + "integrity": "sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.3.tgz", + "integrity": "sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.3.tgz", + "integrity": "sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.3.tgz", + "integrity": "sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.3.tgz", + "integrity": "sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.3.tgz", + "integrity": "sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.3.tgz", + "integrity": "sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.3.tgz", + "integrity": "sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.3.tgz", + "integrity": "sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.3.tgz", + "integrity": "sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.3.tgz", + "integrity": "sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.3.tgz", + "integrity": "sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.3.tgz", + "integrity": "sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.3.tgz", + "integrity": "sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.3.tgz", + "integrity": "sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.3.tgz", + "integrity": "sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.3.tgz", + "integrity": "sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.1.tgz", + "integrity": "sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz", + "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==", + "dependencies": { + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz", + "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", + "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", + "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==" + }, + "node_modules/@formatjs/intl-localematcher": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.6.1.tgz", + "integrity": "sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg==", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.1.tgz", + "integrity": "sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.1.tgz", + "integrity": "sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz", + "integrity": "sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz", + "integrity": "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz", + "integrity": "sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz", + "integrity": "sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz", + "integrity": "sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz", + "integrity": "sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz", + "integrity": "sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz", + "integrity": "sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz", + "integrity": "sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.1.tgz", + "integrity": "sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.1.tgz", + "integrity": "sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.1.tgz", + "integrity": "sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.1.tgz", + "integrity": "sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.1.tgz", + "integrity": "sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.1.tgz", + "integrity": "sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.1.tgz", + "integrity": "sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg==", + "cpu": [ + "wasm32" + ], + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.4.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.1.tgz", + "integrity": "sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.1.tgz", + "integrity": "sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "peer": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "peer": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mdx-js/loader": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@mdx-js/loader/-/loader-2.3.0.tgz", + "integrity": "sha512-IqsscXh7Q3Rzb+f5DXYk0HU71PK+WuFsEhf+mSV3fOhpLcEpgsHvTQ2h0T6TlZ5gHOaBeFjkXwB52by7ypMyNg==", + "dependencies": { + "@mdx-js/mdx": "^2.0.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "webpack": ">=4" + } + }, + "node_modules/@mdx-js/loader/node_modules/@mdx-js/mdx": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-2.3.0.tgz", + "integrity": "sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/mdx": "^2.0.0", + "estree-util-build-jsx": "^2.0.0", + "estree-util-is-identifier-name": "^2.0.0", + "estree-util-to-js": "^1.1.0", + "estree-walker": "^3.0.0", + "hast-util-to-estree": "^2.0.0", + "markdown-extensions": "^1.0.0", + "periscopic": "^3.0.0", + "remark-mdx": "^2.0.0", + "remark-parse": "^10.0.0", + "remark-rehype": "^10.0.0", + "unified": "^10.0.0", + "unist-util-position-from-estree": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "unist-util-visit": "^4.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@mdx-js/loader/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@mdx-js/loader/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" + }, + "node_modules/@mdx-js/loader/node_modules/estree-util-attach-comments": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-2.1.1.tgz", + "integrity": "sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w==", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/estree-util-build-jsx": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-2.2.2.tgz", + "integrity": "sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "estree-util-is-identifier-name": "^2.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/estree-util-is-identifier-name": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-2.1.0.tgz", + "integrity": "sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/estree-util-to-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-1.2.0.tgz", + "integrity": "sha512-IzU74r1PK5IMMGZXUVZbmiu4A1uhiPgW5hm1GjcOfr4ZzHaMPpLNJjR7HjXiIOzi25nZDrgFTobHTkV5Q6ITjA==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/estree-util-visit": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-1.2.1.tgz", + "integrity": "sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/hast-util-to-estree": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-2.3.3.tgz", + "integrity": "sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "estree-util-attach-comments": "^2.0.0", + "estree-util-is-identifier-name": "^2.0.0", + "hast-util-whitespace": "^2.0.0", + "mdast-util-mdx-expression": "^1.0.0", + "mdast-util-mdxjs-esm": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.1", + "unist-util-position": "^4.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/hast-util-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", + "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, + "node_modules/@mdx-js/loader/node_modules/markdown-extensions": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz", + "integrity": "sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/mdast-util-mdx": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-2.0.1.tgz", + "integrity": "sha512-38w5y+r8nyKlGvNjSEqWrhG0w5PmnRA+wnBvm+ulYCct7nsGYhFVb0lljS9bQav4psDAS1eGkP2LMVcZBi/aqw==", + "dependencies": { + "mdast-util-from-markdown": "^1.0.0", + "mdast-util-mdx-expression": "^1.0.0", + "mdast-util-mdx-jsx": "^2.0.0", + "mdast-util-mdxjs-esm": "^1.0.0", + "mdast-util-to-markdown": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/mdast-util-mdx-expression": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-1.3.2.tgz", + "integrity": "sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "mdast-util-from-markdown": "^1.0.0", + "mdast-util-to-markdown": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/mdast-util-mdx-jsx": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-2.1.4.tgz", + "integrity": "sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "ccount": "^2.0.0", + "mdast-util-from-markdown": "^1.1.0", + "mdast-util-to-markdown": "^1.3.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-remove-position": "^4.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/mdast-util-mdxjs-esm": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-1.3.1.tgz", + "integrity": "sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "mdast-util-from-markdown": "^1.0.0", + "mdast-util-to-markdown": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/mdast-util-phrasing": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz", + "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/mdast-util-to-hast": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz", + "integrity": "sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "mdast-util-definitions": "^5.0.0", + "micromark-util-sanitize-uri": "^1.1.0", + "trim-lines": "^3.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/mdast-util-to-markdown": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz", + "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^3.0.0", + "mdast-util-to-string": "^3.0.0", + "micromark-util-decode-string": "^1.0.0", + "unist-util-visit": "^4.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-core-commonmark": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", + "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-factory-destination": "^1.0.0", + "micromark-factory-label": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-factory-title": "^1.0.0", + "micromark-factory-whitespace": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-html-tag-name": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-extension-mdx-expression": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-1.0.8.tgz", + "integrity": "sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "micromark-factory-mdx-expression": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-events-to-acorn": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-extension-mdx-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-1.0.5.tgz", + "integrity": "sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA==", + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "estree-util-is-identifier-name": "^2.0.0", + "micromark-factory-mdx-expression": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-extension-mdx-md": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-1.0.1.tgz", + "integrity": "sha512-7MSuj2S7xjOQXAjjkbjBsHkMtb+mDGVW6uI2dBL9snOBCbZmoNgDAeZ0nSn9j3T42UE/g2xVNMn18PJxZvkBEA==", + "dependencies": { + "micromark-util-types": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-extension-mdxjs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-1.0.1.tgz", + "integrity": "sha512-7YA7hF6i5eKOfFUzZ+0z6avRG52GpWR8DL+kN47y3f2KhxbBZMhmxe7auOeaTBrW2DenbbZTf1ea9tA2hDpC2Q==", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^1.0.0", + "micromark-extension-mdx-jsx": "^1.0.0", + "micromark-extension-mdx-md": "^1.0.0", + "micromark-extension-mdxjs-esm": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-types": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-extension-mdxjs-esm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-1.0.5.tgz", + "integrity": "sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w==", + "dependencies": { + "@types/estree": "^1.0.0", + "micromark-core-commonmark": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-events-to-acorn": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-position-from-estree": "^1.1.0", + "uvu": "^0.5.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-factory-destination": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", + "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-factory-label": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", + "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-factory-mdx-expression": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-1.0.9.tgz", + "integrity": "sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-events-to-acorn": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-position-from-estree": "^1.0.0", + "uvu": "^0.5.0", + "vfile-message": "^3.0.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-factory-title": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-factory-whitespace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-util-chunked": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-util-classify-character": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-util-combine-extensions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-util-decode-numeric-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-util-decode-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-util-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/@mdx-js/loader/node_modules/micromark-util-events-to-acorn": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-1.2.3.tgz", + "integrity": "sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "@types/unist": "^2.0.0", + "estree-util-visit": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0", + "vfile-message": "^3.0.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-util-html-tag-name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/@mdx-js/loader/node_modules/micromark-util-normalize-identifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-util-resolve-all": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-util-sanitize-uri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-util-subtokenize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/@mdx-js/loader/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/@mdx-js/loader/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/@mdx-js/loader/node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/@mdx-js/loader/node_modules/remark-mdx": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-2.3.0.tgz", + "integrity": "sha512-g53hMkpM0I98MU266IzDFMrTD980gNF3BJnkyFcmN+dD873mQeD5rdMO3Y2X+x8umQfbSE0PcoEDl7ledSA+2g==", + "dependencies": { + "mdast-util-mdx": "^2.0.0", + "micromark-extension-mdxjs": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/remark-parse": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz", + "integrity": "sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-from-markdown": "^1.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/remark-rehype": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz", + "integrity": "sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "mdast-util-to-hast": "^12.1.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/style-to-object": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", + "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, + "node_modules/@mdx-js/loader/node_modules/unified": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/unist-util-is": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/unist-util-position": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", + "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/unist-util-position-from-estree": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-1.1.2.tgz", + "integrity": "sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/unist-util-visit": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.1.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/unist-util-visit-parents": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/vfile": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", + "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/loader/node_modules/vfile-message": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", + "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.0.tgz", + "integrity": "sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.9.tgz", + "integrity": "sha512-OKRBiajrrxB9ATokgEQoG87Z25c67pCpYcCwmXYX8PBftC9pBfN18gnm/fh1wurSLEKIAt+QRFLFCQISrb66Jg==", + "dev": true, + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.0", + "@emnapi/runtime": "^1.4.0", + "@tybys/wasm-util": "^0.9.0" + } + }, + "node_modules/@next/env": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.3.1.tgz", + "integrity": "sha512-cwK27QdzrMblHSn9DZRV+DQscHXRuJv6MydlJRpFSqJWZrTYMLzKDeyueJNN9MGd8NNiUKzDQADAf+dMLXX7YQ==" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.3.1.tgz", + "integrity": "sha512-oEs4dsfM6iyER3jTzMm4kDSbrQJq8wZw5fmT6fg2V3SMo+kgG+cShzLfEV20senZzv8VF+puNLheiGPlBGsv2A==", + "dev": true, + "dependencies": { + "fast-glob": "3.3.1" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.3.1.tgz", + "integrity": "sha512-hjDw4f4/nla+6wysBL07z52Gs55Gttp5Bsk5/8AncQLJoisvTBP0pRIBK/B16/KqQyH+uN4Ww8KkcAqJODYH3w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.3.1.tgz", + "integrity": "sha512-q+aw+cJ2ooVYdCEqZVk+T4Ni10jF6Fo5DfpEV51OupMaV5XL6pf3GCzrk6kSSZBsMKZtVC1Zm/xaNBFpA6bJ2g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.3.1.tgz", + "integrity": "sha512-wBQ+jGUI3N0QZyWmmvRHjXjTWFy8o+zPFLSOyAyGFI94oJi+kK/LIZFJXeykvgXUk1NLDAEFDZw/NVINhdk9FQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.3.1.tgz", + "integrity": "sha512-IIxXEXRti/AulO9lWRHiCpUUR8AR/ZYLPALgiIg/9ENzMzLn3l0NSxVdva7R/VDcuSEBo0eGVCe3evSIHNz0Hg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.3.1.tgz", + "integrity": "sha512-bfI4AMhySJbyXQIKH5rmLJ5/BP7bPwuxauTvVEiJ/ADoddaA9fgyNNCcsbu9SlqfHDoZmfI6g2EjzLwbsVTr5A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.3.1.tgz", + "integrity": "sha512-FeAbR7FYMWR+Z+M5iSGytVryKHiAsc0x3Nc3J+FD5NVbD5Mqz7fTSy8CYliXinn7T26nDMbpExRUI/4ekTvoiA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.3.1.tgz", + "integrity": "sha512-yP7FueWjphQEPpJQ2oKmshk/ppOt+0/bB8JC8svPUZNy0Pi3KbPx2Llkzv1p8CoQa+D2wknINlJpHf3vtChVBw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.3.1.tgz", + "integrity": "sha512-3PMvF2zRJAifcRNni9uMk/gulWfWS+qVI/pagd+4yLF5bcXPZPPH2xlYRYOsUjmCJOXSTAC2PjRzbhsRzR2fDQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@orama/orama": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@orama/orama/-/orama-3.1.6.tgz", + "integrity": "sha512-qtSrqCqRU93SjEBedz987tvWao1YQSELjBhGkHYGVP7Dg0lBWP6d+uZEIt5gxTAYio/YWWlhivmRABvRfPLmnQ==", + "engines": { + "node": ">= 16.0.0" + } + }, + "node_modules/@radix-ui/number": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz", + "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==" + }, + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.8.tgz", + "integrity": "sha512-c7OKBvO36PfQIUGIjj1Wko0hH937pYFU2tR5zbIJDUsmTzHoZVHHt4bmb7OOJbzTaWJtVELKWojBHa7OcnUHmQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collapsible": "1.1.8", + "@radix-ui/react-collection": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.0", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.4.tgz", + "integrity": "sha512-qz+fxrqgNxG0dYew5l7qR3c7wdgRu1XVUHGnGYX7rg5HM4p9SWaRmJwfgR3J0SgyUKayLmzQIun+N6rWRgiRKw==", + "dependencies": { + "@radix-ui/react-primitive": "2.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.8.tgz", + "integrity": "sha512-hxEsLvK9WxIAPyxdDRULL4hcaSjMZCfP7fHB0Z1uUnDoDBat1Zh46hwYfa69DeZAbJrPckjf0AGAtEZyvDyJbw==", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.0", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.4.tgz", + "integrity": "sha512-cv4vSf7HttqXilDnAnvINd53OTl1/bjUYVZrkFnA7nwmY9Ob2POUy0WY0sfqBAe1s5FyKsyceQlqiEGPYNTadg==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.0", + "@radix-ui/react-slot": "1.2.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.11.tgz", + "integrity": "sha512-yI7S1ipkP5/+99qhSI6nthfo/tR6bL6Zgxi/+1UO6qPa6UeM6nlafWcQ65vB4rU2XjgjMfMhI3k9Y5MztA62VQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.7", + "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-focus-scope": "1.1.4", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-portal": "1.1.6", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.0", + "@radix-ui/react-slot": "1.2.0", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.7.tgz", + "integrity": "sha512-j5+WBUdhccJsmH5/H0K6RncjDtoALSEr6jbkaZu+bjw6hOPOhHycr6vEUujl+HBK8kjUfWcoCJXxP6e4lUlMZw==", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.0", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz", + "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.4.tgz", + "integrity": "sha512-r2annK27lIW5w9Ho5NyQgqs0MmgZSTIKXWpVCJaLC1q2kZrZkcqnmHkCHMEmv8XLvsLlurKMPT+kbKkRkm/xVA==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.0", + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-navigation-menu": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.10.tgz", + "integrity": "sha512-kGDqMVPj2SRB1vJmXN/jnhC66REAXNyDmDRubbbmJ+360zSIJUDmWGMKIJOf72PHMwPENrbtJVb3CMAUJDjEIA==", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collection": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.0", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.11.tgz", + "integrity": "sha512-yFMfZkVA5G3GJnBgb2PxrrcLKm1ZLWXrbYVgdyTl//0TYEIHS9LJbnyz7WWcZ0qCq7hIlJZpRtxeSeIG5T5oJw==", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.7", + "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-focus-scope": "1.1.4", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.4", + "@radix-ui/react-portal": "1.1.6", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.0", + "@radix-ui/react-slot": "1.2.0", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.4.tgz", + "integrity": "sha512-3p2Rgm/a1cK0r/UVkx5F/K9v/EplfjAeIFCGOPYPO4lZ0jtg4iSQXt/YGTSLWaf4x7NG6Z4+uKFcylcTZjeqDA==", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.0", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.6.tgz", + "integrity": "sha512-XmsIl2z1n/TsYFLIdYam2rmFwf9OC/Sh2avkbmVMDuBZIe7hSpM0cYnWPAo7nHOVx8zTuwDZGByfcqLdnzp3Vw==", + "dependencies": { + "@radix-ui/react-primitive": "2.1.0", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz", + "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.0.tgz", + "integrity": "sha512-/J/FhLdK0zVcILOwt5g+dH4KnkonCtkVJsa2G6JmvbbtZfBEI1gMsO3QMjseL4F/SwfAMt1Vc/0XKYKq+xJ1sw==", + "dependencies": { + "@radix-ui/react-slot": "1.2.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.7.tgz", + "integrity": "sha512-C6oAg451/fQT3EGbWHbCQjYTtbyjNO1uzQgMzwyivcHT3GKNEmu1q3UuREhN+HzHAVtv3ivMVK08QlC+PkYw9Q==", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collection": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.0", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.6.tgz", + "integrity": "sha512-lj8OMlpPERXrQIHlEQdlXHJoRT52AMpBrgyPYylOhXYq5e/glsEdtOc/kCQlsTdtgN5U0iDbrrolDadvektJGQ==", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.0", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz", + "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.9.tgz", + "integrity": "sha512-KIjtwciYvquiW/wAFkELZCVnaNLBsYNhTNcvl+zfMAbMhRkcvNuCLXDDd22L0j7tagpzVh/QwbFpwAATg7ILPw==", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.0", + "@radix-ui/react-roving-focus": "1.1.7", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", + "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", + "dependencies": { + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", + "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.0.tgz", + "integrity": "sha512-rQj0aAWOpCdCMRbI6pLQm8r7S2BM3YhTa0SzOYD55k+hJA8oo9J+H+9wLM9oMlZWOX/wJWPTzfDfmZkf7LvCfg==", + "dependencies": { + "@radix-ui/react-primitive": "2.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", + "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==" + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.11.0.tgz", + "integrity": "sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==", + "dev": true + }, + "node_modules/@shikijs/core": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.3.0.tgz", + "integrity": "sha512-CovkFL2WVaHk6PCrwv6ctlmD4SS1qtIfN8yEyDXDYWh4ONvomdM9MaFw20qHuqJOcb8/xrkqoWQRJ//X10phOQ==", + "dependencies": { + "@shikijs/types": "3.3.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.5" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.3.0.tgz", + "integrity": "sha512-XlhnFGv0glq7pfsoN0KyBCz9FJU678LZdQ2LqlIdAj6JKsg5xpYKay3DkazXWExp3DTJJK9rMOuGzU2911pg7Q==", + "dependencies": { + "@shikijs/types": "3.3.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.2.0" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.3.0.tgz", + "integrity": "sha512-l0vIw+GxeNU7uGnsu6B+Crpeqf+WTQ2Va71cHb5ZYWEVEPdfYwY5kXwYqRJwHrxz9WH+pjSpXQz+TJgAsrkA5A==", + "dependencies": { + "@shikijs/types": "3.3.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.3.0.tgz", + "integrity": "sha512-zt6Kf/7XpBQKSI9eqku+arLkAcDQ3NHJO6zFjiChI8w0Oz6Jjjay7pToottjQGjSDCFk++R85643WbyINcuL+g==", + "dependencies": { + "@shikijs/types": "3.3.0" + } + }, + "node_modules/@shikijs/rehype": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@shikijs/rehype/-/rehype-3.3.0.tgz", + "integrity": "sha512-m9clrxedJHyKDwYoAkIUJ7thWGSZwZbA0PeGDST7NHCTGeS227BFn8Hoq2olAtxXo14k5T1JcUCDgyaRZfI4Hw==", + "dependencies": { + "@shikijs/types": "3.3.0", + "@types/hast": "^3.0.4", + "hast-util-to-string": "^3.0.1", + "shiki": "3.3.0", + "unified": "^11.0.5", + "unist-util-visit": "^5.0.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.3.0.tgz", + "integrity": "sha512-tXeCvLXBnqq34B0YZUEaAD1lD4lmN6TOHAhnHacj4Owh7Ptb/rf5XCDeROZt2rEOk5yuka3OOW2zLqClV7/SOg==", + "dependencies": { + "@shikijs/types": "3.3.0" + } + }, + "node_modules/@shikijs/transformers": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-3.3.0.tgz", + "integrity": "sha512-PIknEyxfkT7i7at/78ynVmuZEv4+7IcS37f6abxMjQ0pVIPEya8n+KNl7XtfbhNL+U9ElR3UzfSzuD5l5Iu+nw==", + "dependencies": { + "@shikijs/core": "3.3.0", + "@shikijs/types": "3.3.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.3.0.tgz", + "integrity": "sha512-KPCGnHG6k06QG/2pnYGbFtFvpVJmC3uIpXrAiPrawETifujPBv0Se2oUxm5qYgjCvGJS9InKvjytOdN+bGuX+Q==", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==" + }, + "node_modules/@sindresorhus/is": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", + "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==" + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==" + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.4.tgz", + "integrity": "sha512-MT5118zaiO6x6hNA04OWInuAiP1YISXql8Z+/Y8iisV5nuhM8VXlyhRuqc2PEviPszcXI66W44bCIk500Oolhw==", + "dev": true, + "dependencies": { + "enhanced-resolve": "^5.18.1", + "jiti": "^2.4.2", + "lightningcss": "1.29.2", + "tailwindcss": "4.1.4" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.4.tgz", + "integrity": "sha512-p5wOpXyOJx7mKh5MXh5oKk+kqcz8T+bA3z/5VWWeQwFrmuBItGwz8Y2CHk/sJ+dNb9B0nYFfn0rj/cKHZyjahQ==", + "dev": true, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.4", + "@tailwindcss/oxide-darwin-arm64": "4.1.4", + "@tailwindcss/oxide-darwin-x64": "4.1.4", + "@tailwindcss/oxide-freebsd-x64": "4.1.4", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.4", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.4", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.4", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.4", + "@tailwindcss/oxide-linux-x64-musl": "4.1.4", + "@tailwindcss/oxide-wasm32-wasi": "4.1.4", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.4", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.4" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.4.tgz", + "integrity": "sha512-xMMAe/SaCN/vHfQYui3fqaBDEXMu22BVwQ33veLc8ep+DNy7CWN52L+TTG9y1K397w9nkzv+Mw+mZWISiqhmlA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.4.tgz", + "integrity": "sha512-JGRj0SYFuDuAGilWFBlshcexev2hOKfNkoX+0QTksKYq2zgF9VY/vVMq9m8IObYnLna0Xlg+ytCi2FN2rOL0Sg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.4.tgz", + "integrity": "sha512-sdDeLNvs3cYeWsEJ4H1DvjOzaGios4QbBTNLVLVs0XQ0V95bffT3+scptzYGPMjm7xv4+qMhCDrkHwhnUySEzA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.4.tgz", + "integrity": "sha512-VHxAqxqdghM83HslPhRsNhHo91McsxRJaEnShJOMu8mHmEj9Ig7ToHJtDukkuLWLzLboh2XSjq/0zO6wgvykNA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.4.tgz", + "integrity": "sha512-OTU/m/eV4gQKxy9r5acuesqaymyeSCnsx1cFto/I1WhPmi5HDxX1nkzb8KYBiwkHIGg7CTfo/AcGzoXAJBxLfg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.4.tgz", + "integrity": "sha512-hKlLNvbmUC6z5g/J4H+Zx7f7w15whSVImokLPmP6ff1QqTVE+TxUM9PGuNsjHvkvlHUtGTdDnOvGNSEUiXI1Ww==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.4.tgz", + "integrity": "sha512-X3As2xhtgPTY/m5edUtddmZ8rCruvBvtxYLMw9OsZdH01L2gS2icsHRwxdU0dMItNfVmrBezueXZCHxVeeb7Aw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.4.tgz", + "integrity": "sha512-2VG4DqhGaDSmYIu6C4ua2vSLXnJsb/C9liej7TuSO04NK+JJJgJucDUgmX6sn7Gw3Cs5ZJ9ZLrnI0QRDOjLfNQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.4.tgz", + "integrity": "sha512-v+mxVgH2kmur/X5Mdrz9m7TsoVjbdYQT0b4Z+dr+I4RvreCNXyCFELZL/DO0M1RsidZTrm6O1eMnV6zlgEzTMQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.4.tgz", + "integrity": "sha512-2TLe9ir+9esCf6Wm+lLWTMbgklIjiF0pbmDnwmhR9MksVOq+e8aP3TSsXySnBDDvTTVd/vKu1aNttEGj3P6l8Q==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.0", + "@emnapi/runtime": "^1.4.0", + "@emnapi/wasi-threads": "^1.0.1", + "@napi-rs/wasm-runtime": "^0.2.8", + "@tybys/wasm-util": "^0.9.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.4.tgz", + "integrity": "sha512-VlnhfilPlO0ltxW9/BgfLI5547PYzqBMPIzRrk4W7uupgCt8z6Trw/tAj6QUtF2om+1MH281Pg+HHUJoLesmng==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.4.tgz", + "integrity": "sha512-+7S63t5zhYjslUGb8NcgLpFXD+Kq1F/zt5Xv5qTv7HaFTG/DHyHD9GA6ieNAxhgyA4IcKa/zy7Xx4Oad2/wuhw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.4.tgz", + "integrity": "sha512-bjV6sqycCEa+AQSt2Kr7wpGF1bOZJ5wsqnLEkqSbM/JEHxx/yhMH8wHmdkPyApF9xhHeMSwnnkDUUMMM/hYnXw==", + "dev": true, + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.1.4", + "@tailwindcss/oxide": "4.1.4", + "postcss": "^8.4.41", + "tailwindcss": "4.1.4" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", + "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", + "dev": true, + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/acorn": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", + "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "peer": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==" + }, + "node_modules/@types/node": { + "version": "22.14.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz", + "integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/react": { + "version": "19.1.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.2.tgz", + "integrity": "sha512-oxLPMytKchWGbnQM9O7D67uPa9paTNxO7jVoNMXgkkErULBPhPARCfkKL9ytcIJJRGjbsVwW4ugJzyFFvm/Tiw==", + "devOptional": true, + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.1.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.2.tgz", + "integrity": "sha512-XGJkWF41Qq305SKWEILa1O8vzhb3aOo3ogBlSmiqNko/WmRb6QIaweuZCXjKygVDXpzXb5wyxKTSOsmkuqj+Qw==", + "devOptional": true, + "peerDependencies": { + "@types/react": "^19.0.0" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.31.0.tgz", + "integrity": "sha512-evaQJZ/J/S4wisevDvC1KFZkPzRetH8kYZbkgcTRyql3mcKsf+ZFDV1BVWUGTCAW5pQHoqn5gK5b8kn7ou9aFQ==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.31.0", + "@typescript-eslint/type-utils": "8.31.0", + "@typescript-eslint/utils": "8.31.0", + "@typescript-eslint/visitor-keys": "8.31.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.31.0.tgz", + "integrity": "sha512-67kYYShjBR0jNI5vsf/c3WG4u+zDnCTHTPqVMQguffaWWFs7artgwKmfwdifl+r6XyM5LYLas/dInj2T0SgJyw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "8.31.0", + "@typescript-eslint/types": "8.31.0", + "@typescript-eslint/typescript-estree": "8.31.0", + "@typescript-eslint/visitor-keys": "8.31.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.31.0.tgz", + "integrity": "sha512-knO8UyF78Nt8O/B64i7TlGXod69ko7z6vJD9uhSlm0qkAbGeRUSudcm0+K/4CrRjrpiHfBCjMWlc08Vav1xwcw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.31.0", + "@typescript-eslint/visitor-keys": "8.31.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.31.0.tgz", + "integrity": "sha512-DJ1N1GdjI7IS7uRlzJuEDCgDQix3ZVYVtgeWEyhyn4iaoitpMBX6Ndd488mXSx0xah/cONAkEaYyylDyAeHMHg==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "8.31.0", + "@typescript-eslint/utils": "8.31.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.31.0.tgz", + "integrity": "sha512-Ch8oSjVyYyJxPQk8pMiP2FFGYatqXQfQIaMp+TpuuLlDachRWpUAeEu1u9B/v/8LToehUIWyiKcA/w5hUFRKuQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.31.0.tgz", + "integrity": "sha512-xLmgn4Yl46xi6aDSZ9KkyfhhtnYI15/CvHbpOy/eR5NWhK/BK8wc709KKwhAR0m4ZKRP7h07bm4BWUYOCuRpQQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.31.0", + "@typescript-eslint/visitor-keys": "8.31.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.31.0.tgz", + "integrity": "sha512-qi6uPLt9cjTFxAb1zGNgTob4x9ur7xC6mHQJ8GwEzGMGE9tYniublmJaowOJ9V2jUzxrltTPfdG2nKlWsq0+Ww==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.31.0", + "@typescript-eslint/types": "8.31.0", + "@typescript-eslint/typescript-estree": "8.31.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.31.0.tgz", + "integrity": "sha512-QcGHmlRHWOl93o64ZUMNewCdwKGU6WItOU52H0djgNmn1EOrhVudrDzXz4OycCRSCPwFCDrE2iIt5vmuUdHxuQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.31.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==" + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.6.4.tgz", + "integrity": "sha512-ehtknxfSIlAIVFmQ9/yVbW4SzyjWuQpKAtRujNzuR0qS1avz4+BSmM0lVhl4OnU7nJaun/g+AM2FeaUY5KwZsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.6.4.tgz", + "integrity": "sha512-CtPj8lqQNVaNjnURq4lCAsanQGN/zO8yFKbL8a7RKH4SU7EMYhOrK8JgW5mbcEDinB4hVuZdgsDCTA3x24CuVQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.6.4.tgz", + "integrity": "sha512-N8UpCG5vis1srGACnJ03WG4N9YfkpzcF7Ooztv9uOE3IG7yjxT4wSVpfbTUof2kOM8TmVhgINoIDQ5wxo+CCxQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.6.4.tgz", + "integrity": "sha512-Hllz4okH+R2P0YdFivGhrA1gjDLjQrhLmfu37TidpQpcp6tcTK40T9mt7SF8frXuPjd2/YNxXIyowOvswwnfOg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.6.4.tgz", + "integrity": "sha512-Mem13rJYfFvBj4xlkuok0zH5qn8vTm9FEm+FyiZeRK/6AFVPc/y596HihKcHIk7djvJ4BYXs7yIZo2ezabE7IA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.6.4.tgz", + "integrity": "sha512-kgyNRMgN7Z2pF2GJBHGIxhkN9e0rMOZwWORH3RjGHZnjtdrThxyQSMUGjK5MDM6+V3waPL0Kv9Y6pJnYxlvcXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.6.4.tgz", + "integrity": "sha512-bLlGWp3Z7eiO6sytt5T3NFwiUfvIjYH9wGIVD01lnVOIBxHUjQQo+7Nv+SkZVP+Y7oySlyyrrzn5y9VFn1MLeQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.6.4.tgz", + "integrity": "sha512-Qt3g8MRemL9h51MCMh4BtQMNzK2JPo2CG8rVeTw8F2xKuUtLRqTsRGitOCbA6cuogv8EezBNyddKKT+bZ70W3g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.6.4.tgz", + "integrity": "sha512-MFMn6TCZZkaOt90lTC+OzfGuGTcOyNDDB6gqgmHEiNUAz8sfljbhKIyms8e792J/Dsq0H1LSWcNhtMjnRZtv8g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.6.4.tgz", + "integrity": "sha512-RGV8V4VjxH8WhcAqvVuHAv85nbdU87dbcJmarXYuAUPLWC76ptJ32eGY5CM4MmmdU8NA3m4EkiBilSvzSt+BMA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.6.4.tgz", + "integrity": "sha512-9SWe0F8kD7+4oD1dLvyHiVXN77PrBKbo46JVuwiCGtv3HnbSgNpjyl/9N4xqsXQScERwRWS6qjjA8fTaedwjRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.6.4.tgz", + "integrity": "sha512-EJP5VyeRTPHqm1CEVoeAcGY7z6fmvAl8MGi06NFxdvczRRwazg0SZre+kzYis/Px4jZY6nZwBXMsHamyY0CELg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.6.4.tgz", + "integrity": "sha512-/Igzy4K6QTajH0m1PesWaYyor/USENYiX7PQQHHsVvewX9rx2mUwpH0ckOLXKpnLNghm+mzDcEufdgFsZQEK3A==", + "cpu": [ + "wasm32" + ], + "dev": true, + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.9" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.6.4.tgz", + "integrity": "sha512-MXx3CyX+XbNJm5HXgZrkiL1JbizaRbpEE1GnXYxIOjfBDFqzWl4tge5Fdp+sBtGeGPB42q6ZBnECEa/tzSWa6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.6.4.tgz", + "integrity": "sha512-ZDIZ4HMZI8GNEUfBaM844O0LfguwDBvpu7orTv+9kxPOAW/6Cxyh768f/qlHIl8Xp0AHZOSJKLc1UneMdt9O6w==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.6.4.tgz", + "integrity": "sha512-jZIMKjruJy9ddDIZBLGzyi2rqfRzi3lNQkQTuaQkcpUMSy+HValMS/fvRHZIB0BGw/fdu2uCDfpxB6dNwB1Ung==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "peer": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "peer": true + }, + "node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "peer": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "peer": true + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/archive-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", + "integrity": "sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==", + "dependencies": { + "file-type": "^4.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/archive-type/node_modules/file-type": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", + "integrity": "sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/aria-hidden": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true + }, + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.10.3", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", + "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "engines": { + "node": "*" + } + }, + "node_modules/bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz", + "integrity": "sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "dependencies": { + "caniuse-lite": "^1.0.30001716", + "electron-to-chromium": "^1.5.149", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dependencies": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "peer": true + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/cacheable-request": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", + "integrity": "sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ==", + "dependencies": { + "clone-response": "1.0.2", + "get-stream": "3.0.0", + "http-cache-semantics": "3.8.1", + "keyv": "3.0.0", + "lowercase-keys": "1.0.0", + "normalize-url": "2.0.1", + "responselike": "1.0.2" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/cacheable-request/node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==" + }, + "node_modules/cacheable-request/node_modules/keyv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", + "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001717", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001717.tgz", + "integrity": "sha512-auPpttCq6BDEG8ZAuHJIplGw6GODhjw+/11e7IjpnYCxZcW/ONgPs0KVBJ0d1bY3e2+7PRe5RCLyP+PfwVgkYw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "peer": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==", + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "optional": true, + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "optional": true, + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/compute-scroll-into-view": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.1.tgz", + "integrity": "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "devOptional": true + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz", + "integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", + "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", + "dependencies": { + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tar": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", + "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "dependencies": { + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tar/node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tarbz2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", + "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "dependencies": { + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tarbz2/node_modules/file-type": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", + "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-targz": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", + "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "dependencies": { + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-targz/node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-unzip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", + "dependencies": { + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-unzip/node_modules/file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-unzip/node_modules/get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", + "dependencies": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-unzip/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress/node_modules/make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress/node_modules/make-dir/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/download": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/download/-/download-8.0.0.tgz", + "integrity": "sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA==", + "dependencies": { + "archive-type": "^4.0.0", + "content-disposition": "^0.5.2", + "decompress": "^4.2.1", + "ext-name": "^5.0.0", + "file-type": "^11.1.0", + "filenamify": "^3.0.0", + "get-stream": "^4.1.0", + "got": "^8.3.1", + "make-dir": "^2.1.0", + "p-event": "^2.1.0", + "pify": "^4.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer3": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", + "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.150", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.150.tgz", + "integrity": "sha512-rOOkP2ZUMx1yL4fCxXQKDHQ8ZXwisb2OycOQVKHgvB3ZI4CvehOd4y2tfnnLDieJ3Zs1RL1Dlp3cMkyIn7nnXA==", + "peer": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/emoji-regex-xs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz", + "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-abstract": { + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "peer": true + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esast-util-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", + "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esast-util-from-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", + "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "acorn": "^8.0.0", + "esast-util-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esbuild": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.3.tgz", + "integrity": "sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.3", + "@esbuild/android-arm": "0.25.3", + "@esbuild/android-arm64": "0.25.3", + "@esbuild/android-x64": "0.25.3", + "@esbuild/darwin-arm64": "0.25.3", + "@esbuild/darwin-x64": "0.25.3", + "@esbuild/freebsd-arm64": "0.25.3", + "@esbuild/freebsd-x64": "0.25.3", + "@esbuild/linux-arm": "0.25.3", + "@esbuild/linux-arm64": "0.25.3", + "@esbuild/linux-ia32": "0.25.3", + "@esbuild/linux-loong64": "0.25.3", + "@esbuild/linux-mips64el": "0.25.3", + "@esbuild/linux-ppc64": "0.25.3", + "@esbuild/linux-riscv64": "0.25.3", + "@esbuild/linux-s390x": "0.25.3", + "@esbuild/linux-x64": "0.25.3", + "@esbuild/netbsd-arm64": "0.25.3", + "@esbuild/netbsd-x64": "0.25.3", + "@esbuild/openbsd-arm64": "0.25.3", + "@esbuild/openbsd-x64": "0.25.3", + "@esbuild/sunos-x64": "0.25.3", + "@esbuild/win32-arm64": "0.25.3", + "@esbuild/win32-ia32": "0.25.3", + "@esbuild/win32-x64": "0.25.3" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-next": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-15.3.1.tgz", + "integrity": "sha512-GnmyVd9TE/Ihe3RrvcafFhXErErtr2jS0JDeCSp3vWvy86AXwHsRBt0E3MqP/m8ACS1ivcsi5uaqjbhsG18qKw==", + "dev": true, + "dependencies": { + "@next/eslint-plugin-next": "15.3.1", + "@rushstack/eslint-patch": "^1.10.3", + "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jsx-a11y": "^6.10.0", + "eslint-plugin-react": "^7.37.0", + "eslint-plugin-react-hooks": "^5.0.0" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0 || ^9.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz", + "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==", + "dev": true, + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.4.0", + "get-tsconfig": "^4.10.0", + "is-bun-module": "^2.0.0", + "stable-hash": "^0.0.5", + "tinyglobby": "^0.2.13", + "unrs-resolver": "^1.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "dev": true, + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dev": true, + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-scope": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", + "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-value-to-estree": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.3.3.tgz", + "integrity": "sha512-Db+m1WSD4+mUO7UgMeKkAwdbfNWwIxLt48XF2oFU9emPfXkIu+k5/nlOj313v7wqtAPo0f9REhUvznFrPkG8CQ==", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "dependencies": { + "mime-db": "^1.28.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "dependencies": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "peer": true + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-type": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-11.1.0.tgz", + "integrity": "sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/filenamify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-3.0.0.tgz", + "integrity": "sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g==", + "dependencies": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.0", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fumadocs-core": { + "version": "15.2.9", + "resolved": "https://registry.npmjs.org/fumadocs-core/-/fumadocs-core-15.2.9.tgz", + "integrity": "sha512-CMclwgXDDdqIA6ZZxEfFvFtkWTN5+X75vIvBlW7BAV4On8oCUOtBl5Whr02rpc7glyKQfOvdKXvHX5xbMHV5WA==", + "dependencies": { + "@formatjs/intl-localematcher": "^0.6.1", + "@orama/orama": "^3.1.6", + "@shikijs/rehype": "^3.2.2", + "@shikijs/transformers": "^3.2.2", + "github-slugger": "^2.0.0", + "hast-util-to-estree": "^3.1.3", + "hast-util-to-jsx-runtime": "^2.3.6", + "image-size": "^2.0.2", + "negotiator": "^1.0.0", + "react-remove-scroll": "^2.6.3", + "remark": "^15.0.0", + "remark-gfm": "^4.0.1", + "scroll-into-view-if-needed": "^3.1.0", + "shiki": "^3.2.2", + "unist-util-visit": "^5.0.0" + }, + "peerDependencies": { + "@oramacloud/client": "1.x.x || 2.x.x", + "algoliasearch": "4.24.0", + "next": "14.x.x || 15.x.x", + "react": "18.x.x || 19.x.x", + "react-dom": "18.x.x || 19.x.x" + }, + "peerDependenciesMeta": { + "@oramacloud/client": { + "optional": true + }, + "algoliasearch": { + "optional": true + }, + "next": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/fumadocs-mdx": { + "version": "11.6.1", + "resolved": "https://registry.npmjs.org/fumadocs-mdx/-/fumadocs-mdx-11.6.1.tgz", + "integrity": "sha512-z+H/eOJC4II0VW7rgf6btqeEkD9DEG1SNToNCYKMklCJAc9Y6l+NuQozKuknP2Ey6NK+Qqhvwhi2MOq38YLSeQ==", + "dependencies": { + "@mdx-js/mdx": "^3.1.0", + "@standard-schema/spec": "^1.0.0", + "chokidar": "^4.0.3", + "cross-spawn": "^7.0.6", + "esbuild": "^0.25.2", + "estree-util-value-to-estree": "^3.3.3", + "fast-glob": "^3.3.3", + "gray-matter": "^4.0.3", + "lru-cache": "^11.1.0", + "picocolors": "^1.1.1", + "unist-util-visit": "^5.0.0", + "zod": "^3.24.3" + }, + "bin": { + "fumadocs-mdx": "bin.js" + }, + "peerDependencies": { + "@fumadocs/mdx-remote": "^1.2.0", + "fumadocs-core": "^14.0.0 || ^15.0.0", + "next": "^15.3.0" + }, + "peerDependenciesMeta": { + "@fumadocs/mdx-remote": { + "optional": true + } + } + }, + "node_modules/fumadocs-mdx/node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fumadocs-mdx/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fumadocs-ui": { + "version": "15.2.9", + "resolved": "https://registry.npmjs.org/fumadocs-ui/-/fumadocs-ui-15.2.9.tgz", + "integrity": "sha512-6bCbWEFc19x6sMi1k+bEKWumOhaPN7N//ih0fNF5OUh6GY3Dfa7NUuGHCfyxFRNAz2dcQQ6YL89L9E35fxoHvg==", + "dependencies": { + "@radix-ui/react-accordion": "^1.2.4", + "@radix-ui/react-collapsible": "^1.1.4", + "@radix-ui/react-dialog": "^1.1.7", + "@radix-ui/react-direction": "^1.1.1", + "@radix-ui/react-navigation-menu": "^1.2.6", + "@radix-ui/react-popover": "^1.1.7", + "@radix-ui/react-scroll-area": "^1.2.4", + "@radix-ui/react-slot": "^1.2.0", + "@radix-ui/react-tabs": "^1.1.4", + "class-variance-authority": "^0.7.1", + "fumadocs-core": "15.2.9", + "lodash.merge": "^4.6.2", + "lucide-react": "^0.488.0", + "next-themes": "^0.4.6", + "postcss-selector-parser": "^7.1.0", + "react-medium-image-zoom": "^5.2.14", + "tailwind-merge": "^3.2.0" + }, + "peerDependencies": { + "next": "14.x.x || 15.x.x", + "react": "18.x.x || 19.x.x", + "react-dom": "18.x.x || 19.x.x", + "tailwindcss": "^3.4.14 || ^4.0.0" + }, + "peerDependenciesMeta": { + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/fumadocs-ui/node_modules/lucide-react": { + "version": "0.488.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.488.0.tgz", + "integrity": "sha512-ronlL0MyKut4CEzBY/ai2ZpKPxyWO4jUqdAkm2GNK5Zn3Rj+swDz+3lvyAUXN0PNqPKIX6XM9Xadwz/skLs/pQ==", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz", + "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==" + }, + "node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "peer": true + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", + "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", + "dependencies": { + "@sindresorhus/is": "^0.7.0", + "cacheable-request": "^2.1.1", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "into-stream": "^3.1.0", + "is-retry-allowed": "^1.1.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.4.0", + "p-timeout": "^2.0.1", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/got/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/got/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "engines": { + "node": "*" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "dependencies": { + "has-symbol-support-x": "^1.4.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz", + "integrity": "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-string": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", + "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-2.0.2.tgz", + "integrity": "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==", + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/inline-style-parser": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", + "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/into-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", + "integrity": "sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==", + "dependencies": { + "from2": "^2.1.1", + "p-is-promise": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "optional": true + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/is-bun-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "dev": true, + "dependencies": { + "semver": "^7.7.1" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-natural-number": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", + "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==" + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-reference": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "dependencies": { + "@types/estree": "^1.0.6" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "dependencies": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "peer": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.2.tgz", + "integrity": "sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==", + "dev": true, + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.29.2", + "lightningcss-darwin-x64": "1.29.2", + "lightningcss-freebsd-x64": "1.29.2", + "lightningcss-linux-arm-gnueabihf": "1.29.2", + "lightningcss-linux-arm64-gnu": "1.29.2", + "lightningcss-linux-arm64-musl": "1.29.2", + "lightningcss-linux-x64-gnu": "1.29.2", + "lightningcss-linux-x64-musl": "1.29.2", + "lightningcss-win32-arm64-msvc": "1.29.2", + "lightningcss-win32-x64-msvc": "1.29.2" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.2.tgz", + "integrity": "sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.2.tgz", + "integrity": "sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.2.tgz", + "integrity": "sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.2.tgz", + "integrity": "sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.2.tgz", + "integrity": "sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.2.tgz", + "integrity": "sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.2.tgz", + "integrity": "sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.2.tgz", + "integrity": "sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.2.tgz", + "integrity": "sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.2.tgz", + "integrity": "sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/loader-utils/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", + "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/lucide-react": { + "version": "0.503.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.503.0.tgz", + "integrity": "sha512-HGGkdlPWQ0vTF8jJ5TdIqhQXZi6uh3LnNgfZ8MHiuxFfX3RZeA79r2MW2tHAZKlAVfoNE8esm3p+O6VkIvpj6w==", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdast-util-definitions": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz", + "integrity": "sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-definitions/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/mdast-util-definitions/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" + }, + "node_modules/mdast-util-definitions/node_modules/unist-util-is": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-definitions/node_modules/unist-util-visit": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.1.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-definitions/node_modules/unist-util-visit-parents": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "peer": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", + "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", + "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", + "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", + "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "peer": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-postinstall": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.1.5.tgz", + "integrity": "sha512-HI5bHONOUYqV+FJvueOSgjRxHTLB25a3xIv59ugAxFe7xRNbW96hyYbMbsKzl+QvFV9mN/SrtHwiU+vYhMwA7Q==", + "dev": true, + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "peer": true + }, + "node_modules/next": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/next/-/next-15.3.1.tgz", + "integrity": "sha512-8+dDV0xNLOgHlyBxP1GwHGVaNXsmp+2NhZEYrXr24GWLHtt27YrBPbPuHvzlhi7kZNYjeJNR93IF5zfFu5UL0g==", + "dependencies": { + "@next/env": "15.3.1", + "@swc/counter": "0.1.3", + "@swc/helpers": "0.5.15", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "15.3.1", + "@next/swc-darwin-x64": "15.3.1", + "@next/swc-linux-arm64-gnu": "15.3.1", + "@next/swc-linux-arm64-musl": "15.3.1", + "@next/swc-linux-x64-gnu": "15.3.1", + "@next/swc-linux-x64-musl": "15.3.1", + "@next/swc-win32-arm64-msvc": "15.3.1", + "@next/swc-win32-x64-msvc": "15.3.1", + "sharp": "^0.34.1" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next-themes": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz", + "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==", + "peerDependencies": { + "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/nextra": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/nextra/-/nextra-1.1.0.tgz", + "integrity": "sha512-WxD1c05gs4cyPHWvqOei9ofIQkLjtzQaDQo8+56f5ss7yJ6ZyI7Ohx7nyyjm6yTo1fO8gfj3v1l/AZmLnjh4FA==", + "dependencies": { + "@mdx-js/loader": "^2.0.0-next.9", + "download": "^8.0.0", + "graceful-fs": "^4.2.6", + "gray-matter": "^4.0.3", + "loader-utils": "^2.0.0", + "remark": "^13.0.0", + "remark-gfm": "^1.0.0", + "slash": "^3.0.0", + "strip-markdown": "^4.0.0" + }, + "peerDependencies": { + "react": ">=16.13.1" + } + }, + "node_modules/nextra/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/nextra/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" + }, + "node_modules/nextra/node_modules/bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/nextra/node_modules/ccount": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", + "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/nextra/node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/nextra/node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/nextra/node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/nextra/node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/nextra/node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/nextra/node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/nextra/node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/nextra/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/nextra/node_modules/longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/nextra/node_modules/markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "dependencies": { + "repeat-string": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/nextra/node_modules/mdast-util-find-and-replace": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz", + "integrity": "sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA==", + "dependencies": { + "escape-string-regexp": "^4.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/mdast-util-from-markdown": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", + "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/mdast-util-gfm": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-0.1.2.tgz", + "integrity": "sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ==", + "dependencies": { + "mdast-util-gfm-autolink-literal": "^0.1.0", + "mdast-util-gfm-strikethrough": "^0.2.0", + "mdast-util-gfm-table": "^0.1.0", + "mdast-util-gfm-task-list-item": "^0.1.0", + "mdast-util-to-markdown": "^0.6.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/mdast-util-gfm-autolink-literal": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.3.tgz", + "integrity": "sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A==", + "dependencies": { + "ccount": "^1.0.0", + "mdast-util-find-and-replace": "^1.1.0", + "micromark": "^2.11.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/mdast-util-gfm-strikethrough": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz", + "integrity": "sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==", + "dependencies": { + "mdast-util-to-markdown": "^0.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/mdast-util-gfm-table": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz", + "integrity": "sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==", + "dependencies": { + "markdown-table": "^2.0.0", + "mdast-util-to-markdown": "~0.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/mdast-util-gfm-task-list-item": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz", + "integrity": "sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==", + "dependencies": { + "mdast-util-to-markdown": "~0.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/mdast-util-to-markdown": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", + "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "longest-streak": "^2.0.0", + "mdast-util-to-string": "^2.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.0.0", + "zwitch": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/mdast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/micromark": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + } + }, + "node_modules/nextra/node_modules/micromark-extension-gfm": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-0.3.3.tgz", + "integrity": "sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A==", + "dependencies": { + "micromark": "~2.11.0", + "micromark-extension-gfm-autolink-literal": "~0.5.0", + "micromark-extension-gfm-strikethrough": "~0.6.5", + "micromark-extension-gfm-table": "~0.4.0", + "micromark-extension-gfm-tagfilter": "~0.3.0", + "micromark-extension-gfm-task-list-item": "~0.3.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/micromark-extension-gfm-autolink-literal": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.7.tgz", + "integrity": "sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw==", + "dependencies": { + "micromark": "~2.11.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/micromark-extension-gfm-strikethrough": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.5.tgz", + "integrity": "sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw==", + "dependencies": { + "micromark": "~2.11.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/micromark-extension-gfm-table": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.3.tgz", + "integrity": "sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA==", + "dependencies": { + "micromark": "~2.11.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/micromark-extension-gfm-tagfilter": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz", + "integrity": "sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/micromark-extension-gfm-task-list-item": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz", + "integrity": "sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==", + "dependencies": { + "micromark": "~2.11.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/nextra/node_modules/remark": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz", + "integrity": "sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==", + "dependencies": { + "remark-parse": "^9.0.0", + "remark-stringify": "^9.0.0", + "unified": "^9.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/remark-gfm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz", + "integrity": "sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==", + "dependencies": { + "mdast-util-gfm": "^0.1.0", + "micromark-extension-gfm": "^0.3.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/remark-parse": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", + "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", + "dependencies": { + "mdast-util-from-markdown": "^0.8.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/remark-stringify": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz", + "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==", + "dependencies": { + "mdast-util-to-markdown": "^0.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/nextra/node_modules/unified": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", + "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", + "dependencies": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", + "trough": "^1.0.0", + "vfile": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/nextra/node_modules/zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "peer": true + }, + "node_modules/normalize-url": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "dependencies": { + "prepend-http": "^2.0.0", + "query-string": "^5.0.1", + "sort-keys": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/oniguruma-parser": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.11.2.tgz", + "integrity": "sha512-F7Ld4oDZJCI5/wCZ8AOffQbqjSzIRpKH7I/iuSs1SkhZeCj0wS6PMZ4W6VA16TWHrAo0Y9bBKEJOe7tvwcTXnw==" + }, + "node_modules/oniguruma-to-es": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.2.0.tgz", + "integrity": "sha512-MDPs6KSOLS0tKQ7joqg44dRIRZUyotfTy0r+7oEEs6VwWWP0+E2PPDYWMFN0aqOjRyWHBYq7RfKw9GQk2S2z5g==", + "dependencies": { + "emoji-regex-xs": "^1.0.0", + "oniguruma-parser": "^0.11.0", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-cancelable": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-event": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz", + "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==", + "dependencies": { + "p-timeout": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-is-promise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "integrity": "sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/property-information": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.0.0.tgz", + "integrity": "sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dependencies": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "node_modules/react-medium-image-zoom": { + "version": "5.2.14", + "resolved": "https://registry.npmjs.org/react-medium-image-zoom/-/react-medium-image-zoom-5.2.14.tgz", + "integrity": "sha512-nfTVYcAUnBzXQpPDcZL+cG/e6UceYUIG+zDcnemL7jtAqbJjVVkA85RgneGtJeni12dTyiRPZVM6Szkmwd/o8w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/rpearce" + } + ], + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-remove-scroll": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.3.tgz", + "integrity": "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/recma-build-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", + "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.0.tgz", + "integrity": "sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==", + "dependencies": { + "acorn-jsx": "^5.0.0", + "estree-util-to-js": "^2.0.0", + "recma-parse": "^1.0.0", + "recma-stringify": "^1.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", + "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", + "dependencies": { + "@types/estree": "^1.0.0", + "esast-util-from-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", + "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-to-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.0.1.tgz", + "integrity": "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rehype-recma": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", + "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "hast-util-to-estree": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/remark/-/remark-15.0.1.tgz", + "integrity": "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==", + "dependencies": { + "@types/mdast": "^4.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.0.tgz", + "integrity": "sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==" + }, + "node_modules/schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "peer": true + }, + "node_modules/scroll-into-view-if-needed": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz", + "integrity": "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==", + "dependencies": { + "compute-scroll-into-view": "^3.0.2" + } + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/seek-bzip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", + "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", + "dependencies": { + "commander": "^2.8.1" + }, + "bin": { + "seek-bunzip": "bin/seek-bunzip", + "seek-table": "bin/seek-bzip-table" + } + }, + "node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "devOptional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sharp": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.1.tgz", + "integrity": "sha512-1j0w61+eVxu7DawFJtnfYcvSv6qPFvfTaqzTQ2BLknVhHTwGS8sc63ZBF4rzkWMBVKybo4S5OBtDdZahh2A1xg==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.7.1" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.1", + "@img/sharp-darwin-x64": "0.34.1", + "@img/sharp-libvips-darwin-arm64": "1.1.0", + "@img/sharp-libvips-darwin-x64": "1.1.0", + "@img/sharp-libvips-linux-arm": "1.1.0", + "@img/sharp-libvips-linux-arm64": "1.1.0", + "@img/sharp-libvips-linux-ppc64": "1.1.0", + "@img/sharp-libvips-linux-s390x": "1.1.0", + "@img/sharp-libvips-linux-x64": "1.1.0", + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0", + "@img/sharp-libvips-linuxmusl-x64": "1.1.0", + "@img/sharp-linux-arm": "0.34.1", + "@img/sharp-linux-arm64": "0.34.1", + "@img/sharp-linux-s390x": "0.34.1", + "@img/sharp-linux-x64": "0.34.1", + "@img/sharp-linuxmusl-arm64": "0.34.1", + "@img/sharp-linuxmusl-x64": "0.34.1", + "@img/sharp-wasm32": "0.34.1", + "@img/sharp-win32-ia32": "0.34.1", + "@img/sharp-win32-x64": "0.34.1" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shiki": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.3.0.tgz", + "integrity": "sha512-j0Z1tG5vlOFGW8JVj0Cpuatzvshes7VJy5ncDmmMaYcmnGW0Js1N81TOW98ivTFNZfKRn9uwEg/aIm638o368g==", + "dependencies": { + "@shikijs/core": "3.3.0", + "@shikijs/engine-javascript": "3.3.0", + "@shikijs/engine-oniguruma": "3.3.0", + "@shikijs/langs": "3.3.0", + "@shikijs/themes": "3.3.0", + "@shikijs/types": "3.3.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "optional": true, + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==", + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sort-keys-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", + "dependencies": { + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys-length/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys-length/node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/stable-hash": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", + "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", + "dev": true + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", + "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "dependencies": { + "is-natural-number": "^4.0.1" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-markdown": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/strip-markdown/-/strip-markdown-4.2.0.tgz", + "integrity": "sha512-sZYHI1KoKOOBfIq78R3E62NHg7kk6aKtZSqiH7wWxFB6Ak6PTZe4N88aJnzjV00Lbfw91oyLpy3baYfTTqNYBA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/style-to-js": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.16.tgz", + "integrity": "sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==", + "dependencies": { + "style-to-object": "1.0.8" + } + }, + "node_modules/style-to-object": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz", + "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==", + "dependencies": { + "inline-style-parser": "0.2.4" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwind-merge": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.2.0.tgz", + "integrity": "sha512-FQT/OVqCD+7edmmJpsgCsY820RTD5AkBryuG5IUqR5YQZSdj5xlH5nLgH7YPths7WsLPSpSBNneJdM8aS8aeFA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.4.tgz", + "integrity": "sha512-1ZIUqtPITFbv/DxRmDr5/agPqJwF69d24m9qmM1939TJehgY539CtzeZRjbLt5G6fSy/7YqqYsfvoTEw9xUI2A==", + "devOptional": true + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dependencies": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/terser": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", + "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", + "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", + "dev": true, + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", + "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "dev": true, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-repeated/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/tw-animate-css": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.2.8.tgz", + "integrity": "sha512-AxSnYRvyFnAiZCUndS3zQZhNfV/B77ZhJ+O7d3K6wfg/jKJY+yv6ahuyXwnyaYA9UdLqnpCwhTRv9pPTBnPR2g==", + "funding": { + "url": "https://github.com/sponsors/Wombosvideo" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==" + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-generated": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz", + "integrity": "sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-4.0.2.tgz", + "integrity": "sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" + }, + "node_modules/unist-util-remove-position/node_modules/unist-util-is": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position/node_modules/unist-util-visit": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.1.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position/node_modules/unist-util-visit-parents": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unrs-resolver": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.6.4.tgz", + "integrity": "sha512-Fb6KH4pQK0XjR5PdRW8BEzsQmbYjkeRHF3IIIZtOVXVFM6Nh+Gb2fQh23Ba7qaYloDp+Aa8/JeNqyImJ8xHlkQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "napi-postinstall": "^0.1.5" + }, + "funding": { + "url": "https://github.com/sponsors/JounQin" + }, + "optionalDependencies": { + "@unrs/resolver-binding-darwin-arm64": "1.6.4", + "@unrs/resolver-binding-darwin-x64": "1.6.4", + "@unrs/resolver-binding-freebsd-x64": "1.6.4", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.6.4", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.6.4", + "@unrs/resolver-binding-linux-arm64-gnu": "1.6.4", + "@unrs/resolver-binding-linux-arm64-musl": "1.6.4", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.6.4", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.6.4", + "@unrs/resolver-binding-linux-s390x-gnu": "1.6.4", + "@unrs/resolver-binding-linux-x64-gnu": "1.6.4", + "@unrs/resolver-binding-linux-x64-musl": "1.6.4", + "@unrs/resolver-binding-wasm32-wasi": "1.6.4", + "@unrs/resolver-binding-win32-arm64-msvc": "1.6.4", + "@unrs/resolver-binding-win32-ia32-msvc": "1.6.4", + "@unrs/resolver-binding-win32-x64-msvc": "1.6.4" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/uvu": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", + "dependencies": { + "dequal": "^2.0.0", + "diff": "^5.0.0", + "kleur": "^4.0.3", + "sade": "^1.7.3" + }, + "bin": { + "uvu": "bin.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.99.8", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.8.tgz", + "integrity": "sha512-lQ3CPiSTpfOnrEGeXDwoq5hIGzSjmwD72GdfVzF7CQAI7t47rJG9eDWvcEkEn3CUQymAElVvDg3YNTlCYj+qUQ==", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.24.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.4.tgz", + "integrity": "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/docs-site/package.json b/docs-site/package.json new file mode 100644 index 00000000..98de417c --- /dev/null +++ b/docs-site/package.json @@ -0,0 +1,41 @@ +{ + "name": "docs-site", + "version": "0.0.0", + "private": true, + "scripts": { + "build": "next build", + "deploy": "gh-pages -d out", + "dev": "next dev --turbopack", + "start": "next start", + "postinstall": "fumadocs-mdx" + }, + "dependencies": { + "@radix-ui/react-accordion": "^1.2.8", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "fumadocs-core": "15.2.9", + "fumadocs-mdx": "11.6.1", + "fumadocs-ui": "^15.2.9", + "lucide-react": "^0.503.0", + "next": "15.3.1", + "nextra": "^1.1.0", + "react": "^19.1.0", + "react-dom": "^19.1.0", + "tailwind-merge": "^3.2.0", + "tw-animate-css": "^1.2.8" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4.1.4", + "@types/mdx": "^2.0.13", + "@types/node": "22.14.1", + "@types/react": "^19.1.2", + "@types/react-dom": "^19.1.2", + "eslint": "^8", + "eslint-config-next": "15.3.1", + "glob": "^8.1.0", + "gray-matter": "^4.0.3", + "postcss": "^8.5.3", + "tailwindcss": "^4.1.4", + "typescript": "^5.8.3" + } +} diff --git a/docs-site/postcss.config.mjs b/docs-site/postcss.config.mjs new file mode 100644 index 00000000..a34a3d56 --- /dev/null +++ b/docs-site/postcss.config.mjs @@ -0,0 +1,5 @@ +export default { + plugins: { + '@tailwindcss/postcss': {}, + }, +}; diff --git a/docs-site/public/1YAKE.ipynb b/docs-site/public/1YAKE.ipynb new file mode 100644 index 00000000..6dbc3f50 --- /dev/null +++ b/docs-site/public/1YAKE.ipynb @@ -0,0 +1,805 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "
YAKE
\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Notebook Developed by**: [Ricardo Campos](http://www.ccc.ipt.pt/~ricardo)
\n", + "**email:** ricardo.campos@ubi.pt
\n", + "**Affiliation:** *Assistant Professor* @ [University of Beira Interior](http://www.ubi.pt);\n", + "*Researcher* @ [LIAAD](https://www.inesctec.pt/en/centres/liaad)-[INESC TEC](https://www.inesctec.pt/en)\n", + "\n", + "
\n", + "\n", + "\n", + "

\"Download

\n", + "

 

\n", + "

 

\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "toc": true + }, + "source": [ + "

Table of Contents

\n", + "
  • 1  YAKE - Yet Another Keyword Extractor
  • 2  Package
    • 2.1  Installation
    • 2.2  Usage (Python)
    • 2.3  Usage (Command Line)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## YAKE - Yet Another Keyword Extractor" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
      " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.display import HTML\n", + "HTML('
      ')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Unsupervised Approach for Automatic Keyword Extraction using Text Features." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "YAKE! is a light-weight unsupervised automatic keyword extraction method which rests on text statistical features extracted from single documents to select the most important keywords of a text. Our system does not need to be trained on a particular set of documents, neither it depends on dictionaries, external-corpus, size of the text, language or domain. To demonstrate the merits and the significance of our proposal, we compare it against ten state-of-the-art unsupervised approaches (TF.IDF, KP-Miner, RAKE, TextRank, SingleRank, ExpandRank, TopicRank, TopicalPageRank, PositionRank and MultipartiteRank), and one supervised method (KEA). Experimental results carried out on top of twenty datasets show that our methods significantly outperform state-of-the-art methods under a number of collections of different sizes, languages or domains. In addition to the python package, we also make available a [demo](http://yake.inesctec.pt) an [API](http://yake.inesctec.pt/apidocs/#!/available_methods/post_yake_v2_extract_keywords) and a [mobile app](https://play.google.com/store/apps/details?id=com.yake.yake)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Main Features" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* Unsupervised approach\n", + "* Corpus-Independent\n", + "* Domain and Language Independent\n", + "* Single-Document" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Rationale" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Extracting keywords from texts has become a challenge for individuals and organizations as the information grows in complexity and size. The need to automate this task so that texts can be processed in a timely and adequate manner has led to the emergence of automatic keyword extraction tools. Despite the advances, there is a clear lack of multilingual online tools to automatically extract keywords from single documents. Yake! is a novel feature-based system for multi-lingual keyword extraction, which supports texts of different sizes, domain or languages. Unlike other approaches, Yake! does not rely on dictionaries nor thesauri, neither is trained against any corpora. Instead, it follows an unsupervised approach which builds upon features extracted from the text, making it thus applicable to documents written in different languages without the need for further knowledge. This can be beneficial for a large number of tasks and a plethora of situations where the access to training corpora is either limited or restricted." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Where can I find YAKE?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "YAKE! is available online [http://yake.inesctec.pt]and as an open source Python package [https://github.com/LIAAD/yake]." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Package" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "### Installation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#!pip install git+http://github.com/LIAAD/yake\n", + "uv pip install yake\n", + "\n", + "#no caso de já ter instalado o package previamente e quiser fazer um update\n", + "#!pip install git+http://github.com/LIAAD/yake --upgrade" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Usage (Python)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "text = '''\n", + "Google is acquiring data science community Kaggle. Sources tell us that Google is acquiring Kaggle, a platform that hosts data science and machine learning competitions. Details about the transaction remain somewhat vague , but given that Google is hosting its Cloud Next conference in San Francisco this week, the official announcement could come as early as tomorrow. Reached by phone, Kaggle co-founder CEO Anthony Goldbloom declined to deny that the acquisition is happening. Google itself declined 'to comment on rumors'. Kaggle, which has about half a million data scientists on its platform, was founded by Goldbloom and Ben Hamner in 2010. The service got an early start and even though it has a few competitors like DrivenData, TopCoder and HackerRank, it has managed to stay well ahead of them by focusing on its specific niche. The service is basically the de facto home for running data science and machine learning competitions. With Kaggle, Google is buying one of the largest and most active communities for data scientists - and with that, it will get increased mindshare in this community, too (though it already has plenty of that thanks to Tensorflow and other projects). Kaggle has a bit of a history with Google, too, but that's pretty recent. Earlier this month, Google and Kaggle teamed up to host a $100,000 machine learning competition around classifying YouTube videos. That competition had some deep integrations with the Google Cloud Platform, too. Our understanding is that Google will keep the service running - likely under its current name. While the acquisition is probably more about Kaggle's community than technology, Kaggle did build some interesting tools for hosting its competition and 'kernels', too. On Kaggle, kernels are basically the source code for analyzing data sets and developers can share this code on the platform (the company previously called them 'scripts'). Like similar competition-centric sites, Kaggle also runs a job board, too. It's unclear what Google will do with that part of the service. According to Crunchbase, Kaggle raised $12.5 million (though PitchBook says it's $12.75) since its launch in 2010. Investors in Kaggle include Index Ventures, SV Angel, Max Levchin, Naval Ravikant, Google chief economist Hal Varian, Khosla Ventures and Yuri Milner'''" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('Google', 0.02509259635302287)\n", + "('Kaggle', 0.027297150442917317)\n", + "('CEO Anthony Goldbloom', 0.04834891465259988)\n", + "('data science', 0.05499112888517541)\n", + "('acquiring data science', 0.06029572445726576)\n", + "('Google Cloud Platform', 0.07461585862381104)\n", + "('data', 0.07999958986489127)\n", + "('San Francisco', 0.0913829662674319)\n", + "('Anthony Goldbloom declined', 0.09740885820462175)\n", + "('science', 0.09834167930168546)\n", + "('science community Kaggle', 0.1014394718805728)\n", + "('machine learning', 0.10754988562466912)\n", + "('Google Cloud', 0.1136787749431024)\n", + "('Google is acquiring', 0.114683257931042)\n", + "('acquiring Kaggle', 0.12012386507741751)\n", + "('Anthony Goldbloom', 0.1213027418574554)\n", + "('platform', 0.12404419723925647)\n", + "('co-founder CEO Anthony', 0.12411964553586782)\n", + "('CEO Anthony', 0.12462950727635251)\n", + "('service', 0.1316357590449064)\n" + ] + } + ], + "source": [ + "import yake\n", + "\n", + "# assuming default parameters\n", + "kw_extractor = yake.KeywordExtractor()\n", + "keywords = kw_extractor.extract_keywords(text)\n", + "\n", + "for kw in keywords:\n", + " print(kw)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Playing with the parameters:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('Google', 0.02509259635302287)\n", + "('Kaggle', 0.027297150442917317)\n", + "('CEO Anthony Goldbloom', 0.04834891465259988)\n", + "('data science', 0.05499112888517541)\n", + "('acquiring data science', 0.06029572445726576)\n", + "('Google Cloud Platform', 0.07461585862381104)\n", + "('data', 0.07999958986489127)\n", + "('San Francisco', 0.0913829662674319)\n", + "('Anthony Goldbloom declined', 0.09740885820462175)\n", + "('science', 0.09834167930168546)\n", + "('science community Kaggle', 0.1014394718805728)\n", + "('machine learning', 0.10754988562466912)\n", + "('Google Cloud', 0.1136787749431024)\n", + "('Google is acquiring', 0.114683257931042)\n", + "('acquiring Kaggle', 0.12012386507741751)\n", + "('Anthony Goldbloom', 0.1213027418574554)\n", + "('platform', 0.12404419723925647)\n", + "('co-founder CEO Anthony', 0.12411964553586782)\n", + "('CEO Anthony', 0.12462950727635251)\n", + "('service', 0.1316357590449064)\n" + ] + } + ], + "source": [ + "import yake\n", + "\n", + "language = \"en\"\n", + "max_ngram_size = 3\n", + "deduplication_thresold = 0.9\n", + "deduplication_algo = 'seqm'\n", + "windowSize = 1\n", + "numOfKeywords = 20\n", + "\n", + "custom_kw_extractor = yake.KeywordExtractor(lan=language, n=max_ngram_size, dedupLim=deduplication_thresold, dedupFunc=deduplication_algo, windowsSize=windowSize, top=numOfKeywords, features=None)\n", + "keywords = custom_kw_extractor.extract_keywords(text)\n", + "\n", + "for kw in keywords:\n", + " print(kw)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('Google', 0.02509259635302287)\n", + "('Kaggle', 0.027297150442917317)\n", + "('CEO Anthony Goldbloom', 0.04834891465259988)\n", + "('data science', 0.05499112888517541)\n", + "('acquiring data science', 0.06029572445726576)\n", + "('Google Cloud Platform', 0.07461585862381104)\n", + "('data', 0.07999958986489127)\n", + "('San Francisco', 0.0913829662674319)\n", + "('Anthony Goldbloom declined', 0.09740885820462175)\n", + "('science', 0.09834167930168546)\n", + "('science community Kaggle', 0.1014394718805728)\n", + "('machine learning', 0.10754988562466912)\n", + "('Google Cloud', 0.1136787749431024)\n", + "('Google is acquiring', 0.114683257931042)\n", + "('acquiring Kaggle', 0.12012386507741751)\n", + "('Anthony Goldbloom', 0.1213027418574554)\n", + "('platform', 0.12404419723925647)\n", + "('co-founder CEO Anthony', 0.12411964553586782)\n", + "('CEO Anthony', 0.12462950727635251)\n", + "('service', 0.1316357590449064)\n" + ] + } + ], + "source": [ + "import yake\n", + "\n", + "language = \"en\"\n", + "max_ngram_size = 3\n", + "deduplication_thresold = 0.9\n", + "deduplication_algo = 'seqm'\n", + "windowSize = 1\n", + "numOfKeywords = 20\n", + "\n", + "custom_kw_extractor = yake.KeywordExtractor(lan=language, n=max_ngram_size, dedupLim=deduplication_thresold, dedupFunc=deduplication_algo, windowsSize=windowSize, top=numOfKeywords, features=None)\n", + "keywords = custom_kw_extractor.extract_keywords(text)\n", + "\n", + "for kw in keywords:\n", + " print(kw)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Highlighting feature will tag every keyword in the text with the default tag ``." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"Google is acquiring data science community Kaggle. Sources tell us that Google is acquiring Kaggle, a platform that hosts data science and machine learning competitions. Details about the transaction remain somewhat vague , but given that Google is hosting its Cloud Next conference in San Francisco this week, the official announcement could come as early as tomorrow. Reached by phone, Kaggle co-founder CEO Anthony Goldbloom declined to deny that the acquisition is happening. Google itself declined 'to comment on rumors'. Kaggle, which has about half a million data scientists on its platform, was founded by Goldbloom and Ben Hamner in 2010. The service got an early start and even though it has a few competitors like DrivenData, TopCoder and HackerRank, it has managed to stay well ahead of them by focusing on its specific niche. The service is basically the de facto home for running data science and machine learning competitions. With Kaggle, Google is buying one of the largest and most active communities for data scientists - and with that, it will get increased mindshare in this community, too (though it already has plenty of that thanks to Tensorflow and other projects). Kaggle has a bit of a history with Google, too, but that's pretty recent. Earlier this month, Google and Kaggle teamed up to host a $100,000 machine learning competition around classifying YouTube videos. That competition had some deep integrations with the Google Cloud Platform, too. Our understanding is that Google will keep the service running - likely under its current name. While the acquisition is probably more about Kaggle's community than technology, Kaggle did build some interesting tools for hosting its competition and 'kernels', too. On Kaggle, kernels are basically the source code for analyzing data sets and developers can share this code on the platform (the company previously called them 'scripts'). Like similar competition-centric sites, Kaggle also runs a job board, too. It's unclear what Google will do with that part of the service. According to Crunchbase, Kaggle raised $12.5 million (though PitchBook says it's $12.75) since its launch in 2010. Investors in Kaggle include Index Ventures, SV Angel, Max Levchin, Naval Ravikant, Google chief economist Hal Varian, Khosla Ventures and Yuri Milner\"" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from yake.highlight import TextHighlighter\n", + "\n", + "th = TextHighlighter(max_ngram_size = 3)\n", + "th.highlight(text, keywords)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Besides tagging a text with the default tag, users can also specify their own custom highlight. In the following text, the tag `` makes use of an hyphotetical function `my_class` whose purpose would be to highlight in white colour or the relevant keywords." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"Google is acquiring data science community Kaggle. Sources tell us that Google is acquiring Kaggle, a platform that hosts data science and machine learning competitions. Details about the transaction remain somewhat vague , but given that Google is hosting its Cloud Next conference in San Francisco this week, the official announcement could come as early as tomorrow. Reached by phone, Kaggle co-founder CEO Anthony Goldbloom declined to deny that the acquisition is happening. Google itself declined 'to comment on rumors'. Kaggle, which has about half a million data scientists on its platform, was founded by Goldbloom and Ben Hamner in 2010. The service got an early start and even though it has a few competitors like DrivenData, TopCoder and HackerRank, it has managed to stay well ahead of them by focusing on its specific niche. The service is basically the de facto home for running data science and machine learning competitions. With Kaggle, Google is buying one of the largest and most active communities for data scientists - and with that, it will get increased mindshare in this community, too (though it already has plenty of that thanks to Tensorflow and other projects). Kaggle has a bit of a history with Google, too, but that's pretty recent. Earlier this month, Google and Kaggle teamed up to host a $100,000 machine learning competition around classifying YouTube videos. That competition had some deep integrations with the Google Cloud Platform, too. Our understanding is that Google will keep the service running - likely under its current name. While the acquisition is probably more about Kaggle's community than technology, Kaggle did build some interesting tools for hosting its competition and 'kernels', too. On Kaggle, kernels are basically the source code for analyzing data sets and developers can share this code on the platform (the company previously called them 'scripts'). Like similar competition-centric sites, Kaggle also runs a job board, too. It's unclear what Google will do with that part of the service. According to Crunchbase, Kaggle raised $12.5 million (though PitchBook says it's $12.75) since its launch in 2010. Investors in Kaggle include Index Ventures, SV Angel, Max Levchin, Naval Ravikant, Google chief economist Hal Varian, Khosla Ventures and Yuri Milner\"" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from yake.highlight import TextHighlighter\n", + "th = TextHighlighter(max_ngram_size = 3, highlight_pre = \"\", highlight_post= \"\")\n", + "th.highlight(text, keywords)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "While English (`en`) is the default language, users can use YAKE! to extract keywords from whatever language they want to by specifying the the corresponding language universal code. The below example shows how to extract keywords from a portuguese text." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('Conta-me Histórias', 0.006225012963810038)\n", + "('LIAAD do INESC', 0.01899063587015275)\n", + "('INESC TEC', 0.01995432290332246)\n", + "('Conta-me', 0.04513273690417472)\n", + "('Histórias', 0.04513273690417472)\n", + "('Prémio Arquivo.pt', 0.05749361520927859)\n", + "('LIAAD', 0.07738867367929901)\n", + "('INESC', 0.07738867367929901)\n", + "('TEC', 0.08109398065524037)\n", + "('Xutos inspiram projeto', 0.08720742489353424)\n", + "('inspiram projeto premiado', 0.08720742489353424)\n", + "('Adam Jatwot docente', 0.09407053486771558)\n", + "('Arquivo.pt', 0.10261392141666957)\n", + "('Alípio Jorge', 0.12190479662535166)\n", + "('Ciências da Universidade', 0.12368384021490342)\n", + "('Ricardo Campos investigador', 0.12789997272332762)\n", + "('Politécnico de Tomar', 0.13323587141127738)\n", + "('Arian Pasquali', 0.13323587141127738)\n", + "('Vitor Mangaravite', 0.13323587141127738)\n", + "('preservados da Web', 0.13596322680882506)\n" + ] + } + ], + "source": [ + "import yake\n", + "\n", + "text = '''\n", + "\"Conta-me Histórias.\" Xutos inspiram projeto premiado. A plataforma \"Conta-me Histórias\" foi distinguida com o Prémio Arquivo.pt, atribuído a trabalhos inovadores de investigação ou aplicação de recursos preservados da Web, através dos serviços de pesquisa e acesso disponibilizados publicamente pelo Arquivo.pt . Nesta plataforma em desenvolvimento, o utilizador pode pesquisar sobre qualquer tema e ainda executar alguns exemplos predefinidos. Como forma de garantir a pluralidade e diversidade de fontes de informação, esta são utilizadas 24 fontes de notícias eletrónicas, incluindo a TSF. Uma versão experimental (beta) do \"Conta-me Histórias\" está disponível aqui.\n", + "A plataforma foi desenvolvida por Ricardo Campos investigador do LIAAD do INESC TEC e docente do Instituto Politécnico de Tomar, Arian Pasquali e Vitor Mangaravite, também investigadores do LIAAD do INESC TEC, Alípio Jorge, coordenador do LIAAD do INESC TEC e docente na Faculdade de Ciências da Universidade do Porto, e Adam Jatwot docente da Universidade de Kyoto.\n", + "'''\n", + "\n", + "custom_kw_extractor = yake.KeywordExtractor(lan=\"pt\")\n", + "keywords = custom_kw_extractor.extract_keywords(text)\n", + "\n", + "for kw in keywords:\n", + " print(kw)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### WordCloud" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the following we are going to constuct a word cloud. To begin, we need to adapt the \"content\" structure to a dictionary consisting of the keyword and of the score. In addition to that, we resort to a normalization function that bounds the values into a range between [0,1]." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Conta-me Histórias': 1.0,\n", + " 'LIAAD do INESC': 0.9016047583205323,\n", + " 'INESC TEC': 0.8941768232148362,\n", + " 'Conta-me': 0.7001059072167914,\n", + " 'Histórias': 0.7001059072167914,\n", + " 'Prémio Arquivo.pt': 0.6048303678150379,\n", + " 'LIAAD': 0.4514826541353427,\n", + " 'INESC': 0.4514826541353427,\n", + " 'TEC': 0.4229227806321687,\n", + " 'Xutos inspiram projeto': 0.37580139629126075,\n", + " 'inspiram projeto premiado': 0.37580139629126075,\n", + " 'Adam Jatwot docente': 0.3229017164607676,\n", + " 'Arquivo.pt': 0.25705075169290126,\n", + " 'Alípio Jorge': 0.10835997942955777,\n", + " 'Ciências da Universidade': 0.09464741520636755,\n", + " 'Ricardo Campos investigador': 0.06215018572037523,\n", + " 'Politécnico de Tomar': 0.021021989718509326,\n", + " 'Arian Pasquali': 0.021021989718509326,\n", + " 'Vitor Mangaravite': 0.021021989718509326,\n", + " 'preservados da Web': 0.0}" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def normalize_scores(keywords):\n", + " if len(keywords) == 0:\n", + " return {}\n", + " max_value = max([item[1] for item in keywords])\n", + " min_value = min([item[1] for item in keywords])\n", + " \n", + " result = {}\n", + " for item in keywords:\n", + " normalized_score = (item[1] - float(min_value))/(float(max_value) - float(min_value))\n", + " result[item[0]] = abs(1 - normalized_score)\n", + "\n", + " return result\n", + "\n", + "keyword2WordCloud = normalize_scores(keywords)\n", + "keyword2WordCloud" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "the following code is a normalizing fuction of the data. The results vary betweent [0,1] where the upper bound isn't necessarly 1 (it can be lower than 1)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```python\n", + "def normalize_scores(keywords):\n", + " if len(keywords) == 0:\n", + " return {}\n", + " max_value = max([item[1] for\n", + " item in keywords])\n", + " \n", + " result = {}\n", + " for item in keywords:\n", + " normalized_score = 1 - item[1]/float(max_value)\n", + " result[item[0]] = abs(normalized_score)\n", + "\n", + " return result\n", + "\n", + "keyword2WordCloud = normalize_scores(keywords)\n", + "keyword2WordCloud\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Later, its possible to build a word cloud using `matplotlib`. If, during installation, you receive an error message stating that Microsoft Visual C++ 14.0 (or higher) is required, you should proceed with its installation. See how to do it on this [web page](https://www.scivision.dev/python-windows-visual-c-14-required/) or in this [video](https://www.youtube.com/watch?v=_keTL9ymGjw)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!uv pip install matplotlib\n", + "!uv pip install wordcloud" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(-0.5, 999.5, 499.5, -0.5)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
      " + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "from wordcloud import WordCloud\n", + "import matplotlib.pyplot as plt\n", + "\n", + "wordcloud = WordCloud(max_font_size=100, max_words = 20, width = 1000, height = 500).generate_from_frequencies(keyword2WordCloud) #Objeto que permite gerar wordcloud a partir de texto\n", + "plt.figure(figsize=(16,9))\n", + "plt.imshow(wordcloud, interpolation=\"bilinear\") #imshow plota imagens que derivam de arrays\n", + "plt.axis(\"off\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now suppose you need to send this image through an API. To achieve this, you should convert the image to base64. The code below allows you to store the image in a buffer and shows its conversion to base64." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import base64\n", + "import io\n", + "from io import BytesIO\n", + "\n", + "buffer = io.BytesIO()\n", + "wordcloud.to_image().save(buffer, 'png')\n", + "b64 = str(base64.b64encode(buffer.getvalue()).decode(\"ascii\"))\n", + "b64" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "From the base64 string, it would then be possible to display the image again." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from io import BytesIO\n", + "from PIL import Image\n", + "\n", + "img1 = Image.open(io.BytesIO(base64.b64decode(b64)))\n", + "img1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Usage (Command Line)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```\n", + "Usage: yake [OPTIONS]\n", + "\n", + "Options:\n", + " --help Show this message and exit.\n", + " -ti, --text_input TEXT Input text, SURROUNDED by single quotes(')\n", + " -i, --input_file TEXT Input file\n", + " -l, --language TEXT Language\n", + " -n, --ngram-size INTEGER Max size of the ngram.\n", + " -df, --dedup-func [leve|jaro|seqm] Deduplication function.\n", + " -dl, --dedup-lim FLOAT Deduplication limiar.\n", + " -ws, --window-size INTEGER Window size.\n", + " -t, --top INTEGER Number of keyphrases to extract\n", + " -v, --verbose Gets detailed information (such as the score)\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A few examples:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```\n", + "yake -i text.txt -l en -n 3\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Related Projects" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- [Spark NLP](https://www.johnsnowlabs.com/spark-nlp-in-action/)\n", + "- [Spark NLP Keywords Extraction Demo](https://demo.johnsnowlabs.com/public/KEYPHRASE_EXTRACTION/)\n", + "- [kaggle](https://www.youtube.com/watch?v=6TBvZmg7AsA)\n", + "- [textacy](https://github.com/chartbeat-labs/textacy/search?q=yake)\n", + "- [pke - pyhton keyphrase extraction](https://github.com/boudinfl/pke)\n", + "- [docker](https://github.com/LIAAD/yake#option-1-yake-as-a-cli-utility-inside-a-docker-container)\n", + "- [dendro](http://dendro-stg.inesctec.pt/)\n", + "- [conta-me histórias](http://contamehistorias.pt)\n", + "- [time-matters](http://time-matters.inesctec.pt)\n", + "- [The General Index](https://archive.org/details/GeneralIndex)\n", + "- [Nature. Giant, free index to world’s research papers released online](https://www.nature.com/articles/d41586-021-02895-8)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Awards" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[ECIR'18](http://ecir2018.org) Best Short Paper (see the below reference)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## References" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Please cite the following works when using YAKE:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**In-depth journal paper at Information Sciences Journal**\n", + "\n", + "- Campos, R., Mangaravite, V., Pasquali, A., Jatowt, A., Jorge, A., Nunes, C. and Jatowt, A. (2020). YAKE! Keyword Extraction from Single Documents using Multiple Local Features. In Information Sciences Journal. Elsevier, Vol 509, pp 257-289. [pdf](https://doi.org/10.1016/j.ins.2019.09.013)\n", + "\n", + "**ECIR'18 Best Short Paper**\n", + "\n", + "- Campos R., Mangaravite V., Pasquali A., Jorge A.M., Nunes C., and Jatowt A. (2018). A Text Feature Based Automatic Keyword Extraction Method for Single Documents. In: Pasi G., Piwowarski B., Azzopardi L., Hanbury A. (eds). Advances in Information Retrieval. ECIR 2018 (Grenoble, France. March 26 – 29). Lecture Notes in Computer Science, vol 10772, pp. 684 - 691. [pdf](https://link.springer.com/chapter/10.1007/978-3-319-76941-7_63)\n", + "\n", + "- Campos R., Mangaravite V., Pasquali A., Jorge A.M., Nunes C., and Jatowt A. (2018). YAKE! Collection-independent Automatic Keyword Extractor. In: Pasi G., Piwowarski B., Azzopardi L., Hanbury A. (eds). Advances in Information Retrieval. ECIR 2018 (Grenoble, France. March 26 – 29). Lecture Notes in Computer Science, vol 10772, pp. 806 - 810. [pdf](https://link.springer.com/chapter/10.1007/978-3-319-76941-7_80)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Media" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- [INESC TEC technology used to create a database of keywords obtained from more than 100 million scientific articles](https://bip.inesctec.pt/en/noticias/inesc-tec-technology-used-to-create-a-database-of-keywords-obtained-from-more-than-100-million-scientific-articles/)\n", + "- [This tool can extract keywords from texts in every language about any topic](https://www.alphagalileo.org/en-gb/Item-Display/ItemId/216276?returnurl=https://www.alphagalileo.org/en-gb/Item-Display/ItemId/216276)\n", + "- [INESC TEC team wins another Best Paper Award](https://www.inesctec.pt/en/news/inesc-tec-team-wins-another-best-paper-award#about)" + ] + } + ], + "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.12.3" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": true, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": true, + "toc_position": { + "height": "calc(100% - 180px)", + "left": "10px", + "top": "150px", + "width": "255px" + }, + "toc_section_display": true, + "toc_window_display": true + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs-site/public/logo_inesctec.png b/docs-site/public/logo_inesctec.png new file mode 100644 index 00000000..eb36b4b3 Binary files /dev/null and b/docs-site/public/logo_inesctec.png differ diff --git a/docs-site/public/yakelogo.png b/docs-site/public/yakelogo.png new file mode 100644 index 00000000..9c2f7afd Binary files /dev/null and b/docs-site/public/yakelogo.png differ diff --git a/docs-site/source.config.ts b/docs-site/source.config.ts new file mode 100644 index 00000000..4cb6ef06 --- /dev/null +++ b/docs-site/source.config.ts @@ -0,0 +1,19 @@ +import { defineDocs, defineConfig, defineCollections } from 'fumadocs-mdx/config'; + +// Options: https://fumadocs.vercel.app/docs/mdx/collections#define-docs +export const docs = defineCollections({ + type: 'doc', + dir: 'content/docs', +}); + +export const meta = defineCollections({ + type: 'meta', + dir: 'content/docs', +}); + + +export default defineConfig({ + mdxOptions: { + // MDX options + }, +}); diff --git a/docs-site/tsconfig.json b/docs-site/tsconfig.json new file mode 100644 index 00000000..7e4699b6 --- /dev/null +++ b/docs-site/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "target": "ESNext", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "paths": { + "@/.source": ["./.source/index.ts"], + "@/*": ["./*"], + "fumadocs-ui/*": ["./node_modules/fumadocs-ui/*"] + }, + "plugins": [ + { + "name": "next" + } + ] + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "types/**/*.d.ts"], + "exclude": ["node_modules"] +} \ No newline at end of file diff --git a/CONTRIBUTING.rst b/docs/CONTRIBUTING.rst similarity index 100% rename from CONTRIBUTING.rst rename to docs/CONTRIBUTING.rst diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 7479bcfa..00000000 --- a/docs/Makefile +++ /dev/null @@ -1,177 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/yake.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/yake.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/yake" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/yake" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/docs/YAKEvsBaselines.jpg b/docs/YAKEvsBaselines.jpg deleted file mode 100644 index 95a4c8a5..00000000 Binary files a/docs/YAKEvsBaselines.jpg and /dev/null differ diff --git a/docs/authors.rst b/docs/authors.rst deleted file mode 100644 index e122f914..00000000 --- a/docs/authors.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../AUTHORS.rst diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100755 index 58f5f37c..00000000 --- a/docs/conf.py +++ /dev/null @@ -1,275 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# yake documentation build configuration file, created by -# sphinx-quickstart on Tue Jul 9 22:26:36 2013. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -import os - -# If extensions (or modules to document with autodoc) are in another -# directory, add these directories to sys.path here. If the directory is -# relative to the documentation root, use os.path.abspath to make it -# absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) - -# Get the project root dir, which is the parent dir of this -cwd = os.getcwd() -project_root = os.path.dirname(cwd) - -# Insert the project root dir as the first element in the PYTHONPATH. -# This lets us ensure that the source package is imported, and that its -# version is used. -sys.path.insert(0, project_root) - -import yake - -# -- General configuration --------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'yake' -copyright = u"2017, Arian Pasquali" - -# The version info for the project you're documenting, acts as replacement -# for |version| and |release|, also used in various other places throughout -# the built documents. -# -# The short X.Y version. -version = yake.__version__ -# The full version, including alpha/beta/rc tags. -release = yake.__version__ - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to -# some non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built -# documents. -#keep_warnings = False - - -# -- Options for HTML output ------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'nature' - -# Theme options are theme-specific and customize the look and feel of a -# theme further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as -# html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the -# top of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon -# of the docs. This file should be a Windows icon file (.ico) being -# 16x16 or 32x32 pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) -# here, relative to this directory. They are copied after the builtin -# static files, so a file named "default.css" will overwrite the builtin -# "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page -# bottom, using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names -# to template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. -# Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. -# Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages -# will contain a tag referring to it. The value of this option -# must be the base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'yakedoc' - - -# -- Options for LaTeX output ------------------------------------------ - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - #'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - #'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - #'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass -# [howto/manual]). -latex_documents = [ - ('index', 'yake.tex', - u'yake Documentation', - u'Arian Pasquali', 'manual'), -] - -# The name of an image file (relative to this directory) to place at -# the top of the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings -# are parts, not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output ------------------------------------ - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'yake', - u'yake Documentation', - [u'Arian Pasquali'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ---------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'yake', - u'yake Documentation', - u'Arian Pasquali', - 'yake', - 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False diff --git a/docs/contributing.rst b/docs/contributing.rst deleted file mode 100644 index e582053e..00000000 --- a/docs/contributing.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../CONTRIBUTING.rst diff --git a/docs/history.rst b/docs/history.rst deleted file mode 100644 index 25064996..00000000 --- a/docs/history.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../HISTORY.rst diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index e940b9c5..00000000 --- a/docs/index.rst +++ /dev/null @@ -1,22 +0,0 @@ -Welcome to yake's documentation! -====================================== - -Contents: - -.. toctree:: - :maxdepth: 2 - - readme - installation - usage - modules - contributing - authors - history - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/docs/installation.rst b/docs/installation.rst deleted file mode 100644 index f7e7dc44..00000000 --- a/docs/installation.rst +++ /dev/null @@ -1,51 +0,0 @@ -.. highlight:: shell - -============ -Installation -============ - - -Stable release --------------- - -To install yake, run this command in your terminal: - -.. code-block:: console - - $ pip install yake - -This is the preferred method to install yake, as it will always install the most recent stable release. - -If you don't have `pip`_ installed, this `Python installation guide`_ can guide -you through the process. - -.. _pip: https://pip.pypa.io -.. _Python installation guide: http://docs.python-guide.org/en/latest/starting/installation/ - - -From sources ------------- - -The sources for yake can be downloaded from the `Github repo`_. - -You can either clone the public repository: - -.. code-block:: console - - $ git clone git://github.com/arrp/yake - -Or download the `tarball`_: - -.. code-block:: console - - $ curl -OL https://github.com/LIAAD/yake/tarball/master - -Once you have a copy of the source, you can install it with: - -.. code-block:: console - - $ python setup.py install - - -.. _Github repo: https://github.com/LIAAD/yake -.. _tarball: https://github.com/LIAAD/yake/tarball/master diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 2dccbc00..00000000 --- a/docs/make.bat +++ /dev/null @@ -1,242 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=_build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . -set I18NSPHINXOPTS=%SPHINXOPTS% . -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. xml to make Docutils-native XML files - echo. pseudoxml to make pseudoxml-XML files for display purposes - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - - -%SPHINXBUILD% 2> nul -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\yake.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\yake.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdf" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf - cd %BUILDDIR%/.. - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdfja" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf-ja - cd %BUILDDIR%/.. - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end -) - -if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -if "%1" == "xml" ( - %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The XML files are in %BUILDDIR%/xml. - goto end -) - -if "%1" == "pseudoxml" ( - %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. - goto end -) - -:end diff --git a/docs/pyake.rst b/docs/pyake.rst deleted file mode 100644 index 40dca838..00000000 --- a/docs/pyake.rst +++ /dev/null @@ -1,46 +0,0 @@ -yake package -============= - -Submodules ----------- - -yake.cli module ----------------- - -.. automodule:: yake.cli - :members: - :undoc-members: - :show-inheritance: - -yake.datarepresentation module -------------------------------- - -.. automodule:: yake.datarepresentation - :members: - :undoc-members: - :show-inheritance: - -yake.keywordextraction module ------------------------------- - -.. automodule:: yake.keywordextraction - :members: - :undoc-members: - :show-inheritance: - -yake.yake module ------------------- - -.. automodule:: yake.yake - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: yake - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/readme.rst b/docs/readme.rst deleted file mode 100644 index 72a33558..00000000 --- a/docs/readme.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../README.rst diff --git a/docs/usage.rst b/docs/usage.rst deleted file mode 100644 index 915e6b20..00000000 --- a/docs/usage.rst +++ /dev/null @@ -1,48 +0,0 @@ -===== -Usage -===== - -To use yake in a project:: - - - import yake - - text_content = """ - - Sources tell us that Google is acquiring Kaggle, a platform that hosts data science and machine learning - competitions. Details about the transaction remain somewhat vague , but given that Google is hosting - its Cloud Next conference in San Francisco this week, the official announcement could come as early - as tomorrow. Reached by phone, Kaggle co-founder CEO Anthony Goldbloom declined to deny that the - acquisition is happening. Google itself declined 'to comment on rumors'. - Kaggle, which has about half a million data scientists on its platform, was founded by Goldbloom - and Ben Hamner in 2010. The service got an early start and even though it has a few competitors - like DrivenData, TopCoder and HackerRank, it has managed to stay well ahead of them by focusing on its - specific niche. The service is basically the de facto home for running data science and machine learning - competitions. With Kaggle, Google is buying one of the largest and most active communities for - data scientists - and with that, it will get increased mindshare in this community, too - (though it already has plenty of that thanks to Tensorflow and other projects). - Kaggle has a bit of a history with Google, too, but that's pretty recent. Earlier this month, - Google and Kaggle teamed up to host a $100,000 machine learning competition around classifying - YouTube videos. That competition had some deep integrations with the Google Cloud Platform, too. - Our understanding is that Google will keep the service running - likely under its current name. - While the acquisition is probably more about Kaggle's community than technology, Kaggle did build - some interesting tools for hosting its competition and 'kernels', too. On Kaggle, kernels are - basically the source code for analyzing data sets and developers can share this code on the - platform (the company previously called them 'scripts'). Like similar competition-centric sites, - Kaggle also runs a job board, too. It's unclear what Google will do with that part of the service. - According to Crunchbase, Kaggle raised $12.5 million (though PitchBook says it's $12.75) since its - launch in 2010. Investors in Kaggle include Index Ventures, SV Angel, Max Levchin, Naval Ravikant, - Google chief economist Hal Varian, Khosla Ventures and Yuri Milner - - """ - - - sample_kwextractor = yake.KeywordExtractor(lan="en",n=3) - result = sample_kwextractor.extract_keywords(text_content) - - keywords = [kw[1] for kw in result] - - for kw in keywords: - print(kw) - - diff --git a/microsoft.gpg b/microsoft.gpg deleted file mode 100644 index 0cffae08..00000000 Binary files a/microsoft.gpg and /dev/null differ diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..c2671023 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4441 @@ +{ + "name": "yake-2.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@types/mdx": "^2.0.13", + "fumadocs-mdx": "^11.6.4" + }, + "devDependencies": { + "gh-pages": "^6.3.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", + "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", + "optional": true, + "peer": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", + "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", + "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", + "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", + "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", + "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", + "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", + "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", + "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", + "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", + "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", + "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", + "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", + "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", + "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", + "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", + "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", + "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", + "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", + "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", + "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", + "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", + "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", + "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", + "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", + "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@formatjs/intl-localematcher": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.6.1.tgz", + "integrity": "sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg==", + "peer": true, + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.1.tgz", + "integrity": "sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.1.tgz", + "integrity": "sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz", + "integrity": "sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz", + "integrity": "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz", + "integrity": "sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz", + "integrity": "sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz", + "integrity": "sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz", + "integrity": "sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz", + "integrity": "sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz", + "integrity": "sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz", + "integrity": "sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.1.tgz", + "integrity": "sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.1.tgz", + "integrity": "sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.1.tgz", + "integrity": "sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.1.tgz", + "integrity": "sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.1.tgz", + "integrity": "sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.1.tgz", + "integrity": "sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.1.tgz", + "integrity": "sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg==", + "cpu": [ + "wasm32" + ], + "optional": true, + "peer": true, + "dependencies": { + "@emnapi/runtime": "^1.4.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.1.tgz", + "integrity": "sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.1.tgz", + "integrity": "sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.0.tgz", + "integrity": "sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@next/env": { + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.3.2.tgz", + "integrity": "sha512-xURk++7P7qR9JG1jJtLzPzf0qEvqCN0A/T3DXf8IPMKo9/6FfjxtEffRJIIew/bIL4T3C2jLLqBor8B/zVlx6g==", + "peer": true + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.3.2.tgz", + "integrity": "sha512-2DR6kY/OGcokbnCsjHpNeQblqCZ85/1j6njYSkzRdpLn5At7OkSdmk7WyAmB9G0k25+VgqVZ/u356OSoQZ3z0g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.3.2.tgz", + "integrity": "sha512-ro/fdqaZWL6k1S/5CLv1I0DaZfDVJkWNaUU3un8Lg6m0YENWlDulmIWzV96Iou2wEYyEsZq51mwV8+XQXqMp3w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.3.2.tgz", + "integrity": "sha512-covwwtZYhlbRWK2HlYX9835qXum4xYZ3E2Mra1mdQ+0ICGoMiw1+nVAn4d9Bo7R3JqSmK1grMq/va+0cdh7bJA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.3.2.tgz", + "integrity": "sha512-KQkMEillvlW5Qk5mtGA/3Yz0/tzpNlSw6/3/ttsV1lNtMuOHcGii3zVeXZyi4EJmmLDKYcTcByV2wVsOhDt/zg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.3.2.tgz", + "integrity": "sha512-uRBo6THWei0chz+Y5j37qzx+BtoDRFIkDzZjlpCItBRXyMPIg079eIkOCl3aqr2tkxL4HFyJ4GHDes7W8HuAUg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.3.2.tgz", + "integrity": "sha512-+uxFlPuCNx/T9PdMClOqeE8USKzj8tVz37KflT3Kdbx/LOlZBRI2yxuIcmx1mPNK8DwSOMNCr4ureSet7eyC0w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.3.2.tgz", + "integrity": "sha512-LLTKmaI5cfD8dVzh5Vt7+OMo+AIOClEdIU/TSKbXXT2iScUTSxOGoBhfuv+FU8R9MLmrkIL1e2fBMkEEjYAtPQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.3.2.tgz", + "integrity": "sha512-aW5B8wOPioJ4mBdMDXkt5f3j8pUr9W8AnlX0Df35uRWNT1Y6RIybxjnSUe+PhM+M1bwgyY8PHLmXZC6zT1o5tA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@orama/orama": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@orama/orama/-/orama-3.1.7.tgz", + "integrity": "sha512-6yB0117ZjsgNevZw3LP+bkrZa9mU/POPVaXgzMPOBbBc35w2P3R+1vMMhEfC06kYCpd5bf0jodBaTkYQW5TVeQ==", + "peer": true, + "engines": { + "node": ">= 20.0.0" + } + }, + "node_modules/@shikijs/core": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.4.2.tgz", + "integrity": "sha512-AG8vnSi1W2pbgR2B911EfGqtLE9c4hQBYkv/x7Z+Kt0VxhgQKcW7UNDVYsu9YxwV6u+OJrvdJrMq6DNWoBjihQ==", + "peer": true, + "dependencies": { + "@shikijs/types": "3.4.2", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.5" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.4.2.tgz", + "integrity": "sha512-1/adJbSMBOkpScCE/SB6XkjJU17ANln3Wky7lOmrnpl+zBdQ1qXUJg2GXTYVHRq+2j3hd1DesmElTXYDgtfSOQ==", + "peer": true, + "dependencies": { + "@shikijs/types": "3.4.2", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.3.3" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.4.2.tgz", + "integrity": "sha512-zcZKMnNndgRa3ORja6Iemsr3DrLtkX3cAF7lTJkdMB6v9alhlBsX9uNiCpqofNrXOvpA3h6lHcLJxgCIhVOU5Q==", + "peer": true, + "dependencies": { + "@shikijs/types": "3.4.2", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.4.2.tgz", + "integrity": "sha512-H6azIAM+OXD98yztIfs/KH5H4PU39t+SREhmM8LaNXyUrqj2mx+zVkr8MWYqjceSjDw9I1jawm1WdFqU806rMA==", + "peer": true, + "dependencies": { + "@shikijs/types": "3.4.2" + } + }, + "node_modules/@shikijs/rehype": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@shikijs/rehype/-/rehype-3.4.2.tgz", + "integrity": "sha512-atbsrT3UKs25OdKVbNoHyKO9ZP7KEBPlo1oanPGMkvUL0fLictpxMPz6vPE2YTeHhpwz7EMrA4K4FHRY8XAReg==", + "peer": true, + "dependencies": { + "@shikijs/types": "3.4.2", + "@types/hast": "^3.0.4", + "hast-util-to-string": "^3.0.1", + "shiki": "3.4.2", + "unified": "^11.0.5", + "unist-util-visit": "^5.0.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.4.2.tgz", + "integrity": "sha512-qAEuAQh+brd8Jyej2UDDf+b4V2g1Rm8aBIdvt32XhDPrHvDkEnpb7Kzc9hSuHUxz0Iuflmq7elaDuQAP9bHIhg==", + "peer": true, + "dependencies": { + "@shikijs/types": "3.4.2" + } + }, + "node_modules/@shikijs/transformers": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-3.4.2.tgz", + "integrity": "sha512-I5baLVi/ynLEOZoWSAMlACHNnG+yw5HDmse0oe+GW6U1u+ULdEB3UHiVWaHoJSSONV7tlcVxuaMy74sREDkSvg==", + "peer": true, + "dependencies": { + "@shikijs/core": "3.4.2", + "@shikijs/types": "3.4.2" + } + }, + "node_modules/@shikijs/types": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.4.2.tgz", + "integrity": "sha512-zHC1l7L+eQlDXLnxvM9R91Efh2V4+rN3oMVS2swCBssbj2U/FBwybD1eeLaq8yl/iwT+zih8iUbTBCgGZOYlVg==", + "peer": true, + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "peer": true + }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==" + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "peer": true + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "peer": true, + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==" + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==" + }, + "node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "peer": true, + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001718", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz", + "integrity": "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "peer": true + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "optional": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "optional": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "optional": true, + "peer": true + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "optional": true, + "peer": true, + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/compute-scroll-into-view": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.1.tgz", + "integrity": "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==", + "peer": true + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz", + "integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "peer": true + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/email-addresses": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", + "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", + "dev": true + }, + "node_modules/esast-util-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", + "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esast-util-from-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", + "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "acorn": "^8.0.0", + "esast-util-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esbuild": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", + "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.4", + "@esbuild/android-arm": "0.25.4", + "@esbuild/android-arm64": "0.25.4", + "@esbuild/android-x64": "0.25.4", + "@esbuild/darwin-arm64": "0.25.4", + "@esbuild/darwin-x64": "0.25.4", + "@esbuild/freebsd-arm64": "0.25.4", + "@esbuild/freebsd-x64": "0.25.4", + "@esbuild/linux-arm": "0.25.4", + "@esbuild/linux-arm64": "0.25.4", + "@esbuild/linux-ia32": "0.25.4", + "@esbuild/linux-loong64": "0.25.4", + "@esbuild/linux-mips64el": "0.25.4", + "@esbuild/linux-ppc64": "0.25.4", + "@esbuild/linux-riscv64": "0.25.4", + "@esbuild/linux-s390x": "0.25.4", + "@esbuild/linux-x64": "0.25.4", + "@esbuild/netbsd-arm64": "0.25.4", + "@esbuild/netbsd-x64": "0.25.4", + "@esbuild/openbsd-arm64": "0.25.4", + "@esbuild/openbsd-x64": "0.25.4", + "@esbuild/sunos-x64": "0.25.4", + "@esbuild/win32-arm64": "0.25.4", + "@esbuild/win32-ia32": "0.25.4", + "@esbuild/win32-x64": "0.25.4" + } + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-scope": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", + "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-value-to-estree": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.4.0.tgz", + "integrity": "sha512-Zlp+gxis+gCfK12d3Srl2PdX2ybsEA8ZYy6vQGVQTNNYLEGRQQ56XB64bjemN8kxIKXP1nC9ip4Z+ILy9LGzvQ==", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "dev": true, + "dependencies": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fumadocs-core": { + "version": "15.3.3", + "resolved": "https://registry.npmjs.org/fumadocs-core/-/fumadocs-core-15.3.3.tgz", + "integrity": "sha512-3i547DisQ/k4v5UYECgTIi14be2TGrnomwT6AKOis+Nj0A8sUdaMEU6KgYT9GAOUeeC6A733pSm6Bi8aY91/IQ==", + "peer": true, + "dependencies": { + "@formatjs/intl-localematcher": "^0.6.1", + "@orama/orama": "^3.1.6", + "@shikijs/rehype": "^3.4.2", + "@shikijs/transformers": "^3.4.2", + "github-slugger": "^2.0.0", + "hast-util-to-estree": "^3.1.3", + "hast-util-to-jsx-runtime": "^2.3.6", + "image-size": "^2.0.2", + "negotiator": "^1.0.0", + "react-remove-scroll": "^2.6.3", + "remark": "^15.0.0", + "remark-gfm": "^4.0.1", + "scroll-into-view-if-needed": "^3.1.0", + "shiki": "^3.4.2", + "unist-util-visit": "^5.0.0" + }, + "peerDependencies": { + "@oramacloud/client": "1.x.x || 2.x.x", + "algoliasearch": "4.24.0", + "next": "14.x.x || 15.x.x", + "react": "18.x.x || 19.x.x", + "react-dom": "18.x.x || 19.x.x" + }, + "peerDependenciesMeta": { + "@oramacloud/client": { + "optional": true + }, + "algoliasearch": { + "optional": true + }, + "next": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/fumadocs-mdx": { + "version": "11.6.4", + "resolved": "https://registry.npmjs.org/fumadocs-mdx/-/fumadocs-mdx-11.6.4.tgz", + "integrity": "sha512-pGczNrR+w31JJ8/L9TfFFoe0dGNV43suz2YXyz1iD1yQ2j2VldLqYZ12UyRi7IsqTiVBFUSkRks1iYBRvNr/4w==", + "dependencies": { + "@mdx-js/mdx": "^3.1.0", + "@standard-schema/spec": "^1.0.0", + "chokidar": "^4.0.3", + "cross-spawn": "^7.0.6", + "esbuild": "^0.25.4", + "estree-util-value-to-estree": "^3.4.0", + "fast-glob": "^3.3.3", + "gray-matter": "^4.0.3", + "js-yaml": "^4.1.0", + "lru-cache": "^11.1.0", + "picocolors": "^1.1.1", + "unist-util-visit": "^5.0.0", + "zod": "^3.24.4" + }, + "bin": { + "fumadocs-mdx": "bin.js" + }, + "peerDependencies": { + "@fumadocs/mdx-remote": "^1.2.0", + "fumadocs-core": "^14.0.0 || ^15.0.0", + "next": "^15.3.0" + }, + "peerDependenciesMeta": { + "@fumadocs/mdx-remote": { + "optional": true + } + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/gh-pages": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.3.0.tgz", + "integrity": "sha512-Ot5lU6jK0Eb+sszG8pciXdjMXdBJ5wODvgjR+imihTqsUWF2K6dJ9HST55lgqcs8wWcw6o6wAsUzfcYRhJPXbA==", + "dev": true, + "dependencies": { + "async": "^3.2.4", + "commander": "^13.0.0", + "email-addresses": "^5.0.0", + "filenamify": "^4.3.0", + "find-cache-dir": "^3.3.1", + "fs-extra": "^11.1.1", + "globby": "^11.1.0" + }, + "bin": { + "gh-pages": "bin/gh-pages.js", + "gh-pages-clean": "bin/gh-pages-clean.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "peer": true + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz", + "integrity": "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "peer": true, + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-string": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", + "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", + "peer": true, + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "peer": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-2.0.2.tgz", + "integrity": "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==", + "peer": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/inline-style-parser": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", + "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==" + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "optional": true, + "peer": true + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", + "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "peer": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "peer": true, + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "peer": true, + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "peer": true, + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "peer": true, + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "peer": true, + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "peer": true, + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "peer": true, + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "peer": true, + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "peer": true, + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "peer": true, + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "peer": true, + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "peer": true, + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "peer": true, + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "peer": true, + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", + "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", + "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", + "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", + "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/next": { + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/next/-/next-15.3.2.tgz", + "integrity": "sha512-CA3BatMyHkxZ48sgOCLdVHjFU36N7TF1HhqAHLFOkV6buwZnvMI84Cug8xD56B9mCuKrqXnLn94417GrZ/jjCQ==", + "peer": true, + "dependencies": { + "@next/env": "15.3.2", + "@swc/counter": "0.1.3", + "@swc/helpers": "0.5.15", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "15.3.2", + "@next/swc-darwin-x64": "15.3.2", + "@next/swc-linux-arm64-gnu": "15.3.2", + "@next/swc-linux-arm64-musl": "15.3.2", + "@next/swc-linux-x64-gnu": "15.3.2", + "@next/swc-linux-x64-musl": "15.3.2", + "@next/swc-win32-arm64-msvc": "15.3.2", + "@next/swc-win32-x64-msvc": "15.3.2", + "sharp": "^0.34.1" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/oniguruma-parser": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", + "integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==", + "peer": true + }, + "node_modules/oniguruma-to-es": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.3.tgz", + "integrity": "sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==", + "peer": true, + "dependencies": { + "oniguruma-parser": "^0.12.1", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "peer": true, + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.0" + } + }, + "node_modules/react-remove-scroll": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.0.tgz", + "integrity": "sha512-sGsQtcjMqdQyijAHytfGEELB8FufGbfXIsvUTe+NLx1GDRJCXtCFLBLUI1eyZCKXXvbEU2C6gai0PZKoIE9Vbg==", + "peer": true, + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "peer": true, + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "peer": true, + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/recma-build-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", + "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.0.tgz", + "integrity": "sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==", + "dependencies": { + "acorn-jsx": "^5.0.0", + "estree-util-to-js": "^2.0.0", + "recma-parse": "^1.0.0", + "recma-stringify": "^1.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", + "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", + "dependencies": { + "@types/estree": "^1.0.0", + "esast-util-from-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", + "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-to-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.0.1.tgz", + "integrity": "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==", + "peer": true, + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "peer": true, + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "peer": true + }, + "node_modules/rehype-recma": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", + "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "hast-util-to-estree": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/remark/-/remark-15.0.1.tgz", + "integrity": "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==", + "peer": true, + "dependencies": { + "@types/mdast": "^4.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "peer": true, + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.0.tgz", + "integrity": "sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "peer": true, + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "peer": true + }, + "node_modules/scroll-into-view-if-needed": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz", + "integrity": "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==", + "peer": true, + "dependencies": { + "compute-scroll-into-view": "^3.0.2" + } + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.1.tgz", + "integrity": "sha512-1j0w61+eVxu7DawFJtnfYcvSv6qPFvfTaqzTQ2BLknVhHTwGS8sc63ZBF4rzkWMBVKybo4S5OBtDdZahh2A1xg==", + "hasInstallScript": true, + "optional": true, + "peer": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.7.1" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.1", + "@img/sharp-darwin-x64": "0.34.1", + "@img/sharp-libvips-darwin-arm64": "1.1.0", + "@img/sharp-libvips-darwin-x64": "1.1.0", + "@img/sharp-libvips-linux-arm": "1.1.0", + "@img/sharp-libvips-linux-arm64": "1.1.0", + "@img/sharp-libvips-linux-ppc64": "1.1.0", + "@img/sharp-libvips-linux-s390x": "1.1.0", + "@img/sharp-libvips-linux-x64": "1.1.0", + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0", + "@img/sharp-libvips-linuxmusl-x64": "1.1.0", + "@img/sharp-linux-arm": "0.34.1", + "@img/sharp-linux-arm64": "0.34.1", + "@img/sharp-linux-s390x": "0.34.1", + "@img/sharp-linux-x64": "0.34.1", + "@img/sharp-linuxmusl-arm64": "0.34.1", + "@img/sharp-linuxmusl-x64": "0.34.1", + "@img/sharp-wasm32": "0.34.1", + "@img/sharp-win32-ia32": "0.34.1", + "@img/sharp-win32-x64": "0.34.1" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shiki": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.4.2.tgz", + "integrity": "sha512-wuxzZzQG8kvZndD7nustrNFIKYJ1jJoWIPaBpVe2+KHSvtzMi4SBjOxrigs8qeqce/l3U0cwiC+VAkLKSunHQQ==", + "peer": true, + "dependencies": { + "@shikijs/core": "3.4.2", + "@shikijs/engine-javascript": "3.4.2", + "@shikijs/engine-oniguruma": "3.4.2", + "@shikijs/langs": "3.4.2", + "@shikijs/themes": "3.4.2", + "@shikijs/types": "3.4.2", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "optional": true, + "peer": true, + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "peer": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/style-to-js": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.16.tgz", + "integrity": "sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==", + "dependencies": { + "style-to-object": "1.0.8" + } + }, + "node_modules/style-to-object": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz", + "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==", + "dependencies": { + "inline-style-parser": "0.2.4" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "peer": true, + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-repeated/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "peer": true + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "peer": true, + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "peer": true, + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/zod": { + "version": "3.25.7", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.7.tgz", + "integrity": "sha512-YGdT1cVRmKkOg6Sq7vY7IkxdphySKnXhaUmFI4r4FcuFVNgpCb9tZfNwXbT6BPjD5oz0nubFsoo9pIqKrDcCvg==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..38b19483 --- /dev/null +++ b/package.json @@ -0,0 +1,9 @@ +{ + "devDependencies": { + "gh-pages": "^6.3.0" + }, + "dependencies": { + "@types/mdx": "^2.0.13", + "fumadocs-mdx": "^11.6.4" + } +} diff --git a/pke/yake.py b/pke/yake.py deleted file mode 100644 index 05b23072..00000000 --- a/pke/yake.py +++ /dev/null @@ -1,462 +0,0 @@ -# -*- coding: utf-8 -*- -# Author: Florian Boudin and Vítor Mangaravite -# Date: 09-10-2018 - -"""YAKE keyphrase extraction model. - -Statistical approach to keyphrase extraction described in: - -* Ricardo Campos, Vítor Mangaravite, Arian Pasquali, Alípio Mário Jorge, - Célia Nunes and Adam Jatowt. - YAKE! Collection-Independent Automatic Keyword Extractor. - *Proceedings of ECIR*, pages 806-810, 2018. - -""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import math -import re -import string -from collections import defaultdict - -import numpy -from nltk.metrics import edit_distance - -from pke.base import LoadFile - - -class YAKE(LoadFile): - """YAKE keyphrase extraction model. - - Parameterized example:: - - import pke - from nltk.corpus import stopwords - - # 1. create a YAKE extractor. - extractor = pke.unsupervised.YAKE() - - # 2. load the content of the document. - extractor.load_document(input='path/to/input', - language='en', - normalization=None) - - - # 3. select {1-3}-grams not containing punctuation marks and not - # beginning/ending with a stopword as candidates. - stoplist = stopwords.words('english') - extractor.candidate_selection(n=3, stoplist=stoplist) - - # 4. weight the candidates using YAKE weighting scheme, a window (in - # words) for computing left/right contexts can be specified. - window = 2 - use_stems = False # use stems instead of words for weighting - extractor.candidate_weighting(window=window, - stoplist=stoplist, - use_stems=use_stems) - - # 5. get the 10-highest scored candidates as keyphrases. - # redundant keyphrases are removed from the output using levenshtein - # distance and a threshold. - threshold = 0.8 - keyphrases = extractor.get_n_best(n=10, threshold=threshold) - """ - - def __init__(self): - """Redefining initializer for YAKE. - """ - - super(YAKE, self).__init__() - - self.words = defaultdict(set) - """ Container for the vocabulary. """ - - self.contexts = defaultdict(lambda: ([], [])) - """ Container for word contexts. """ - - self.features = defaultdict(dict) - """ Container for word features. """ - - self.surface_to_lexical = {} - """ Mapping from surface form to lexical form. """ - - def candidate_selection(self, n=3, stoplist=None, **kwargs): - """Select 1-3 grams as keyphrase candidates. Candidates beginning or - ending with a stopword are filtered out. Words that do not contain - at least one alpha-numeric character are not allowed. - - Args: - n (int): the n-gram length, defaults to 3. - stoplist (list): the stoplist for filtering candidates, defaults to - the nltk stoplist. - """ - - # select ngrams from 1 to 3 grams - self.ngram_selection(n=n) - - # filter candidates containing punctuation marks - self.candidate_filtering( - stoplist=list(string.punctuation) + - ['-lrb-', '-rrb-', '-lcb-', '-rcb-', '-lsb-', '-rsb-'] - ) - - # initialize empty list if stoplist is not provided - if stoplist is None: - stoplist = self.stoplist - - # further filter candidates - for k in list(self.candidates): - - # get the candidate - v = self.candidates[k] - - # filter candidates starting/ending with a stopword - if v.surface_forms[0][0].lower() in stoplist or \ - v.surface_forms[0][-1].lower() in stoplist or \ - len(v.surface_forms[0][0]) < 3 or \ - len(v.surface_forms[0][-1]) < 3: - del self.candidates[k] - - def _vocabulary_building(self, use_stems=False): - """Build the vocabulary that will be used to weight candidates. Only - words containing at least one alpha-numeric character are kept. - - Args: - use_stems (bool): whether to use stems instead of lowercase words - for weighting, defaults to False. - """ - - # loop through sentences - for i, sentence in enumerate(self.sentences): - - # compute the offset shift for the sentence - shift = sum([s.length for s in self.sentences[0:i]]) - - # loop through words in sentence - for j, word in enumerate(sentence.words): - - # consider words containing at least one alpha-numeric character - if self._is_alphanum(word) and \ - not re.search('(?i)^-[lr][rcs]b-$', word): - - # get the word or stem - index = word.lower() - if use_stems: - index = sentence.stems[j] - - # add the word occurrence - self.words[index].add((shift + j, shift, i, word)) - - def _contexts_building(self, use_stems=False, window=2): - """Build the contexts of the words for computing the relatdeness - feature. Words that occur within a window of n words are considered as - context words. - - Args: - use_stems (bool): whether to use stems instead of lowercase words - for weighting, defaults to False. - window (int): the size in words of the window used for computing - co-occurrence counts, defaults to 2. - """ - # change: split sentence to block of words - # (this is important to avoid consider cooccurrence between terms like word1 and word2 on sentence "word1, word2") - - # loop through sentences - for i, sentence in enumerate(self.sentences): - - # lowercase the words - words = [w.lower() for w in sentence.words] - - # replace with stems if needed - if use_stems: - words = sentence.stems - - - buffer = [] - # loop through words in sentence - for j, word in enumerate(words): - - # skip if word is not in vocabulary - if word not in self.words: - buffer = [] - continue - - # add the right context - for w in [ w for w in buffer[max(0, len(buffer) - window):len(buffer)] ]: - self.contexts[word][0].append(w) - self.contexts[w][1].append(word) - - buffer.append(word) - buffer = [] - - def _feature_extraction(self, stoplist=None): - """Compute the weight of individual words using the following five - features: - - 1. CASING: gives importance to acronyms or words starting with a - capital letter. - - CASING(w) = max(TF(U(w)), TF(A(w))) / (1 + log(TF(w))) - - with TF(U(w) being the # times the word starts with an uppercase - letter, excepts beginning of sentences. TF(A(w)) is the # times - the word is marked as an acronym. - - 2. POSITION: gives importance to words occurring at the beginning of - the document. - - POSITION(w) = log( log( 3 + Median(Sen(w)) ) ) - - with Sen(w) contains the position of the sentences where w - occurs. - - 3. FREQUENCY: gives importance to frequent words. - - FREQUENCY(w) = TF(w) / ( MEAN_TF + STD_TF) - - with MEAN_TF and STD_TF computed on valid_tfs which are words - that are not stopwords. - - 4. RELATEDNESS: gives importance to words that do not have the - characteristics of stopwords. - - RELATEDNESS(w) = 1 + (WR+WL)*(TF(w)/MAX_TF) + PL + PR - - 5. DIFFERENT: gives importance to words that occurs in multiple - sentences. - - DIFFERENT(w) = SF(w) / # sentences - - with SF(w) being the sentence frequency of word w. - - Args: - stoplist (list): the stoplist for filtering candidates, defaults to - the nltk stoplist. - """ - # change: Update the WRel feature generation - - # initialize stoplist list if not provided - if stoplist is None: - stoplist = self.stoplist - - # get the Term Frequency of each word - TF = [len(self.words[w]) for w in self.words] - - # get the Term Frequency of non-stop words - TF_nsw = [len(self.words[w]) for w in self.words if w not in stoplist] - - # compute statistics - mean_TF = numpy.mean(TF_nsw) - std_TF = numpy.std(TF_nsw) - max_TF = max(TF) - - # Loop through the words - for word in self.words: - self.features[word]['isstop'] = word in stoplist or len(word) < 3 - - # Term Frequency - self.features[word]['TF'] = len(self.words[word]) - - # Uppercase/Acronym Term Frequencies - self.features[word]['TF_A'] = 0 - self.features[word]['TF_U'] = 0 - for (offset, shift, sent_id, surface_form) in self.words[word]: - if surface_form.isupper() and len(word) > 1: - self.features[word]['TF_A'] += 1 - elif surface_form[0].isupper() and offset != shift: - self.features[word]['TF_U'] += 1 - - # 1. CASING feature - self.features[word]['CASING'] = max(self.features[word]['TF_A'], - self.features[word]['TF_U']) - self.features[word]['CASING'] /= 1.0 + math.log( - self.features[word]['TF']) - - # 2. POSITION feature - sentence_ids = list(set([t[2] for t in self.words[word]])) - self.features[word]['POSITION'] = math.log(3.0 + numpy.median(sentence_ids)) - self.features[word]['POSITION'] = math.log(self.features[word]['POSITION']) - - # 3. FREQUENCY feature - self.features[word]['FREQUENCY'] = self.features[word]['TF'] - self.features[word]['FREQUENCY'] /= (mean_TF + std_TF) - - # 4. RELATEDNESS feature - self.features[word]['WL'] = 0.0 - if len(self.contexts[word][0]): - self.features[word]['WL'] = len(set(self.contexts[word][0])) - self.features[word]['WL'] /= len(self.contexts[word][0]) - self.features[word]['PL'] = len(set(self.contexts[word][0])) / max_TF - - self.features[word]['WR'] = 0.0 - if len(self.contexts[word][1]): - self.features[word]['WR'] = len(set(self.contexts[word][1])) - self.features[word]['WR'] /= len(self.contexts[word][1]) - self.features[word]['PR'] = len(set(self.contexts[word][1])) / max_TF - - self.features[word]['RELATEDNESS'] = 1 - #self.features[word]['RELATEDNESS'] += self.features[word]['PL'] - #self.features[word]['RELATEDNESS'] += self.features[word]['PR'] - self.features[word]['RELATEDNESS'] += (self.features[word]['WR'] + - self.features[word]['WL']) * \ - (self.features[word]['TF'] / max_TF) - - # 5. DIFFERENT feature - self.features[word]['DIFFERENT'] = len(set(sentence_ids)) - self.features[word]['DIFFERENT'] /= len(self.sentences) - - # assemble the features to weight words - A = self.features[word]['CASING'] - B = self.features[word]['POSITION'] - C = self.features[word]['FREQUENCY'] - D = self.features[word]['RELATEDNESS'] - E = self.features[word]['DIFFERENT'] - self.features[word]['weight'] = (D * B) / (A + (C / D) + (E / D)) - - def candidate_weighting(self, window=2, stoplist=None, use_stems=False): - """Candidate weight calculation as described in the YAKE paper. - - Args: - stoplist (list): the stoplist for filtering candidates, defaults to - the nltk stoplist. - use_stems (bool): whether to use stems instead of lowercase words - for weighting, defaults to False. - window (int): the size in words of the window used for computing - co-occurrence counts, defaults to 2. - """ - # change: Consider stopwords between non-stopwords on condidate weight generation - - # build the vocabulary - self._vocabulary_building(use_stems=use_stems) - - # extract the contexts - self._contexts_building(use_stems=use_stems, window=window) - - # compute the word features - self._feature_extraction(stoplist=stoplist) - - # compute candidate weights - for k, v in self.candidates.items(): - - # use stems - if use_stems: - weights = [self.features[t]['weight'] for t in v.lexical_form] - self.weights[k] = numpy.prod(weights) - self.weights[k] /= len(v.offsets) * (1 + sum(weights)) - - # use words - else: - lowercase_forms = [' '.join(t).lower() for t in v.surface_forms] - for i, candidate in enumerate(lowercase_forms): - TF = lowercase_forms.count(candidate) - words_cand = [t.lower() for t in v.surface_forms[i]] - prod_ = 1. - sum_ = 0. - for j, word_cand in enumerate(words_cand): - if self.features[word_cand]['isstop']: - """ - self.contexts[word][0].append(w) # left - self.contexts[w][1].append(word) # right - """ - term_left = words_cand[j-1] - term_right = words_cand[j+1] - term_stop = word_cand - - prob_t1 = self.contexts[term_left][1].count(term_stop) / self.features[term_left]['TF'] - - prob_t2 = self.contexts[term_stop][0].count(term_right) / self.features[term_right]['TF'] - - prob = prob_t1 * prob_t2 - prod_ *= (1 + (1 - prob ) ) - sum_ -= (1 - prob) - else: - prod_ *= self.features[word_cand]['weight'] - sum_ += self.features[word_cand]['weight'] - self.weights[candidate] = prod_ - self.weights[candidate] /= TF * (1 + sum_) - self.surface_to_lexical[candidate] = k - - def is_redundant(self, candidate, prev, threshold=0.8): - """Test if one candidate is redundant with respect to a list of already - selected candidates. A candidate is considered redundant if its - levenshtein distance, with another candidate that is ranked higher in - the list, is greater than a threshold. - - Args: - candidate (str): the lexical form of the candidate. - prev (list): the list of already selected candidates. - threshold (float): the threshold used when computing the - levenshtein distance, defaults to 0.8. - """ - - # loop through the already selected candidates - for prev_candidate in prev: - dist = edit_distance(candidate, prev_candidate) - dist /= max(len(candidate), len(prev_candidate)) - if (1.0 - dist) > threshold: - return True - return False - - def get_n_best(self, - n=10, - redundancy_removal=True, - stemming=False, - threshold=0.8): - """ Returns the n-best candidates given the weights. - - Args: - n (int): the number of candidates, defaults to 10. - redundancy_removal (bool): whether redundant keyphrases are - filtered out from the n-best list using levenshtein - distance, defaults to True. - stemming (bool): whether to extract stems or surface forms - (lowercased, first occurring form of candidate), default to - stems. - threshold (float): the threshold used when computing the - levenshtein distance, defaults to 0.8. - """ - - # sort candidates by ascending weight - best = sorted(self.weights, key=self.weights.get, reverse=False) - - # remove redundant candidates - if redundancy_removal: - - # initialize a new container for non redundant candidates - non_redundant_best = [] - - # loop through the best candidates - for candidate in best: - - # test wether candidate is redundant - if self.is_redundant(candidate, non_redundant_best): - continue - - # add the candidate otherwise - non_redundant_best.append(candidate) - - # break computation if the n-best are found - if len(non_redundant_best) >= n: - break - - # copy non redundant candidates in best container - best = non_redundant_best - - # get the list of best candidates as (lexical form, weight) tuples - n_best = [(u, self.weights[u]) for u in best[:min(n, len(best))]] - - # replace with surface forms if no stemming - if stemming: - for i, (candidate, weight) in enumerate(n_best): - - if candidate not in self.candidates: - candidate = self.surface_to_lexical[candidate] - - candidate = ' '.join(self.candidates[candidate].lexical_form) - n_best[i] = (candidate, weight) - - # return the list of best candidates - return n_best diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..ee14e214 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,55 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "yake" +version = "0.6.0" +description = "Keyword extraction Python package" +readme = "README.md" +requires-python = ">=3.10" +license = {text = "LGPLv3"} +authors = [ + {name = "Arian Pasquali", email = "arianpasquali@gmail.com"}, + {name = "Ricadro Campos", email = "ricardo.campos@ubi.pt"}, + {name = "Tiago Vaente", email = "tiago.leando.valente@ubi.com"}, +] +dependencies = [ + "tabulate", + "segtok", + "networkx", + "numpy>=1.23.5", # This version requires Python >=3.8 + "click>=6.0", + "jellyfish", +] +classifiers = [ + "Development Status :: 3 - Alpha", + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Programming Language :: Python :: 3", + # Remove Python 3.5, 3.6, 3.7 classifiers + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Topic :: Scientific/Engineering :: Information Analysis", + "Topic :: Software Development :: Libraries", + "Topic :: Text Processing", + "Topic :: Text Processing :: Linguistic", +] + +[project.optional-dependencies] +dev = [ + "pytest", + "flake8", + "pytest-runner", # Added from setup_requirements +] + +[project.urls] +Documentation = "https://tiagolv.github.io/yakerf/docs/--home" +Source = "https://github.com/LIAAD/yake" + +[project.scripts] +yake = "yake.cli:keywords" + +[tool.hatch.build.targets.wheel] +packages = ["yake", "StopwordsList"] # Explicitly include these packages diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index c3fdc611..00000000 --- a/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -tabulate -pytest -flake8 -segtok -jellyfish -networkx -numpy -click diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 62c06d4d..00000000 --- a/setup.cfg +++ /dev/null @@ -1,28 +0,0 @@ -[bumpversion] -current_version = 0.4.8 -commit = True -tag = True - -[bumpversion:file:setup.py] -search = version='{current_version}' -replace = version='{new_version}' - -[bumpversion:file:yake/__init__.py] -search = __version__ = '{current_version}' -replace = __version__ = '{new_version}' - -[bdist_wheel] -universal = 1 - -[flake8] -exclude = docs - -[aliases] -test = pytest - -[metadata] -description-file = README.rst - -[egg_info] -tag_build = -tag_date = 0 diff --git a/setup.py b/setup.py deleted file mode 100644 index d1cf7fb7..00000000 --- a/setup.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -"""The setup script.""" - -from setuptools import setup, find_packages - -readme = """ -# Yet Another Keyword Extractor (Yake) - -Unsupervised Approach for Automatic Keyword Extraction using Text Features. - -YAKE! is a light-weight unsupervised automatic keyword extraction method which rests on text statistical features extracted from single documents to select the most important keywords of a text. Our system does not need to be trained on a particular set of documents, neither it depends on dictionaries, external-corpus, size of the text, language or domain. To demonstrate the merits and the significance of our proposal, we compare it against ten state-of-the-art unsupervised approaches (TF.IDF, KP-Miner, RAKE, TextRank, SingleRank, ExpandRank, TopicRank, TopicalPageRank, PositionRank and MultipartiteRank), and one supervised method (KEA). Experimental results carried out on top of twenty datasets (see Benchmark section below) show that our methods significantly outperform state-of-the-art methods under a number of collections of different sizes, languages or domains. In addition to the python package here described, we also make available a demo, an API and a mobile app. - -## Main Features - -* Unsupervised approach -* Corpus-Independent -* Domain and Language Independent -* Single-Document - -## Where can I find YAKE!? -YAKE! is available online [http://yake.inesctec.pt], as an open source Python package [https://github.com/LIAAD/yake] and on [Google Play](https://play.google.com/store/apps/details?id=com.yake.yake). - -## References -Please cite the following works when using YAKE - -In-depth journal paper at Information Sciences Journal - -Campos, R., Mangaravite, V., Pasquali, A., Jatowt, A., Jorge, A., Nunes, C. and Jatowt, A. (2020). YAKE! Keyword Extraction from Single Documents using Multiple Local Features. In Information Sciences Journal. Elsevier, Vol 509, pp 257-289. [pdf](https://doi.org/10.1016/j.ins.2019.09.013) - -ECIR'18 Best Short Paper - -Campos R., Mangaravite V., Pasquali A., Jorge A.M., Nunes C., and Jatowt A. (2018). A Text Feature Based Automatic Keyword Extraction Method for Single Documents. In: Pasi G., Piwowarski B., Azzopardi L., Hanbury A. (eds). Advances in Information Retrieval. ECIR 2018 (Grenoble, France. March 26 – 29). Lecture Notes in Computer Science, vol 10772, pp. 684 - 691. [pdf](https://link.springer.com/chapter/10.1007/978-3-319-76941-7_63) - -Campos R., Mangaravite V., Pasquali A., Jorge A.M., Nunes C., and Jatowt A. (2018). YAKE! Collection-independent Automatic Keyword Extractor. In: Pasi G., Piwowarski B., Azzopardi L., Hanbury A. (eds). Advances in Information Retrieval. ECIR 2018 (Grenoble, France. March 26 – 29). Lecture Notes in Computer Science, vol 10772, pp. 806 - 810. [pdf](https://link.springer.com/chapter/10.1007/978-3-319-76941-7_80) - -## Awards -[ECIR'18](http://ecir2018.org) Best Short Paper -""" -requirements = [ - 'tabulate', - 'click>=6.0', - "numpy", - "segtok", - "networkx", - "jellyfish"] - -setup_requirements = [ - 'pytest-runner' -] - -test_requirements = [ - "pytest", - "flake8" -] - -setup( - name='yake', - version='0.4.8', - description="Keyword extraction Python package", - long_description=readme, - long_description_content_type='text/markdown', - url='https://pypi.python.org/pypi/yake', - project_urls={ - 'Documentation': 'https://liaad.github.io/yake/', - 'Source': 'https://github.com/LIAAD/yake', - }, - packages=find_packages(include=['yake','StopwordsList']), - entry_points={ - 'console_scripts': [ - 'yake=yake.cli:keywords' - ] - }, - license="LGPLv3", - include_package_data=True, - install_requires=requirements, - zip_safe=False, - keywords='yake', -classifiers=[ - 'Development Status :: 3 - Alpha', - "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Topic :: Scientific/Engineering :: Information Analysis', - 'Topic :: Software Development :: Libraries', - 'Topic :: Text Processing', - 'Topic :: Text Processing :: Linguistic', - ], - test_suite='tests', - tests_require=test_requirements, - setup_requires=setup_requirements, -) diff --git a/strategy.ini b/strategy.ini deleted file mode 100644 index 0fe10d28..00000000 --- a/strategy.ini +++ /dev/null @@ -1,26 +0,0 @@ -# Authorized and unauthorized licenses in LOWER CASE -[Licenses] -authorized_licenses: - bsd - new bsd - bsd license - new bsd license - simplified bsd - apache - apache 2.0 - apache software license - gnu lgpl - lgpl with exceptions or zpl - isc license - isc license (iscl) - mit - mit license - python software foundation license - zpl 2.1 - -unauthorized_licenses: - gpl v3 - -[Authorized Packages] -# Python software license (see http://zesty.ca/python/uuid.README.txt) -uuid: 1.30 diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 00000000..d8f25bbb --- /dev/null +++ b/tests/README.md @@ -0,0 +1,18 @@ +# 🧪 How to run the tests +This project uses pytes to run it´s tests. + +### 📋 Pre-requirements +If not already installed install pytest: + +bash +``` +pip install pytest +``` + +### 🚀 Running the tests +To run the tests, run the following command on the root of your project: + +bash +``` +pytest tests/test_yake.py -v +``` diff --git a/tests/__pycache__/__init__.cpython-310.pyc b/tests/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..3d4bf687 Binary files /dev/null and b/tests/__pycache__/__init__.cpython-310.pyc differ diff --git a/tests/__pycache__/test_yake.cpython-310-pytest-8.3.4.pyc b/tests/__pycache__/test_yake.cpython-310-pytest-8.3.4.pyc new file mode 100644 index 00000000..79fdc372 Binary files /dev/null and b/tests/__pycache__/test_yake.cpython-310-pytest-8.3.4.pyc differ diff --git a/tests/doc1.txt b/tests/doc1.txt deleted file mode 100644 index 7ef9c955..00000000 --- a/tests/doc1.txt +++ /dev/null @@ -1 +0,0 @@ -Sources tell us that Google is acquiring Kaggle, a platform that hosts data science and machine learning competitions. Details about the transaction remain somewhat vague , but given that Google is hosting its Cloud Next conference in San Francisco this week, the official announcement could come as early as tomorrow. Reached by phone, Kaggle co-founder CEO Anthony Goldbloom declined to deny that the acquisition is happening. Google itself declined 'to comment on rumors'. Kaggle, which has about half a million data scientists on its platform, was founded by Goldbloom and Ben Hamner in 2010. The service got an early start and even though it has a few competitors like DrivenData, TopCoder and HackerRank, it has managed to stay well ahead of them by focusing on its specific niche. The service is basically the de facto home for running data science and machine learning competitions. With Kaggle, Google is buying one of the largest and most active communities for data scientists - and with that, it will get increased mindshare in this community, too (though it already has plenty of that thanks to Tensorflow and other projects). Kaggle has a bit of a history with Google, too, but that's pretty recent. Earlier this month, Google and Kaggle teamed up to host a $100,000 machine learning competition around classifying YouTube videos. That competition had some deep integrations with the Google Cloud Platform, too. Our understanding is that Google will keep the service running - likely under its current name. While the acquisition is probably more about Kaggle's community than technology, Kaggle did build some interesting tools for hosting its competition and 'kernels', too. On Kaggle, kernels are basically the source code for analyzing data sets and developers can share this code on the platform (the company previously called them 'scripts'). Like similar competition-centric sites, Kaggle also runs a job board, too. It's unclear what Google will do with that part of the service. According to Crunchbase, Kaggle raised $12.5 million (though PitchBook says it's $12.75) since its launch in 2010. Investors in Kaggle include Index Ventures, SV Angel, Max Levchin, Naval Ravikant, Google chief economist Hal Varian, Khosla Ventures and Yuri Milner \ No newline at end of file diff --git a/tests/test_yake.py b/tests/test_yake.py index 27f760d7..d724b992 100644 --- a/tests/test_yake.py +++ b/tests/test_yake.py @@ -3,12 +3,11 @@ """Tests for yake package.""" -import pytest from click.testing import CliRunner import yake -from yake.highlight import TextHighlighter +from yake.core.highlight import TextHighlighter def test_phraseless_example(): text_content = "- not yet" @@ -20,7 +19,7 @@ def test_phraseless_example(): def test_null_and_blank_example(): pyake = yake.KeywordExtractor() - + result = pyake.extract_keywords("") assert len(result) == 0 @@ -111,7 +110,7 @@ def test_n1_EL(): text_content = ''' Ανώτατος διοικητής του ÏÏ‰ÏƒÎ¹ÎºÎ¿Ï ÏƒÏ„ÏÎ±Ï„Î¿Ï Ï†Î­Ïεται να σκοτώθηκε κοντά στο ΧάÏκοβο, σÏμφωνα με την υπηÏεσία πληÏοφοÏιών του υπουÏγείου Άμυνας της ΟυκÏανίας. ΣÏμφωνα με δήλωση του υπουÏγείου Άμυνας της ΟυκÏανίας, Ï€Ïόκειται για τον Vitaly Gerasimov, υποστÏάτηγο και υποδιοικητή από την ΚεντÏική ΣτÏατιωτική ΠεÏιφέÏεια της Ρωσίας.''' - pyake = yake.KeywordExtractor(lan="el",n=1) + pyake = yake.KeywordExtractor(lan="el", n=1) result = pyake.extract_keywords(text_content) print(result) res = [('ΟυκÏανίας', 0.04685829498124156), ('ΧάÏκοβο', 0.0630891548728466), ('Άμυνας', 0.06395408991254226), ('σÏμφωνα', 0.07419311338418161), ('υπουÏγείου', 0.1069960715371627), ('Ανώτατος', 0.12696931063105557), ('διοικητής', 0.18516501832552387), ('ÏωσικοÏ', 0.18516501832552387), ('στÏατοÏ', 0.18516501832552387), ('φέÏεται', 0.18516501832552387), ('σκοτώθηκε', 0.18516501832552387), ('κοντά', 0.18516501832552387), ('υπηÏεσία', 0.18516501832552387), ('πληÏοφοÏιών', 0.18516501832552387), ('Gerasimov', 0.1895400421770795), ('Ρωσίας', 0.1895400421770795), ('Vitaly', 0.24366598777562623), ('ΚεντÏική', 0.24366598777562623), ('ΣτÏατιωτική', 0.24366598777562623), ('ΠεÏιφέÏεια', 0.24366598777562623)] @@ -129,4 +128,4 @@ def test_n1_EL(): test_n1_EN() test_n3_EN() test_n3_PT() -test_n1_EL() \ No newline at end of file +test_n1_EL() diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..6ce6984b --- /dev/null +++ b/uv.lock @@ -0,0 +1,437 @@ +version = 1 +revision = 2 +requires-python = ">=3.10" + +[[package]] +name = "click" +version = "8.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" }, +] + +[[package]] +name = "flake8" +version = "7.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mccabe" }, + { name = "pycodestyle" }, + { name = "pyflakes" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e7/c4/5842fc9fc94584c455543540af62fd9900faade32511fab650e9891ec225/flake8-7.2.0.tar.gz", hash = "sha256:fa558ae3f6f7dbf2b4f22663e5343b6b6023620461f8d4ff2019ef4b5ee70426", size = 48177, upload-time = "2025-03-29T20:08:39.329Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/5c/0627be4c9976d56b1217cb5187b7504e7fd7d3503f8bfd312a04077bd4f7/flake8-7.2.0-py2.py3-none-any.whl", hash = "sha256:93b92ba5bdb60754a6da14fa3b93a9361fd00a59632ada61fd7b130436c40343", size = 57786, upload-time = "2025-03-29T20:08:37.902Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, +] + +[[package]] +name = "jellyfish" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/29/c0d39be806b5d5c201e9bf5265e43cf0e88bd63fb4e38edfc7a212ca38a7/jellyfish-1.2.0.tar.gz", hash = "sha256:5c7d73db4045dcc53b6efbfea21f3d3da432d3e052dc51827574d1a447fc23b4", size = 364693, upload-time = "2025-03-31T15:43:18.43Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/9c/1d3102a61776d44e8028af5a38a2638a6d4ad8ad719cf48a6bfe6b8ce894/jellyfish-1.2.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:50b6d2a123d3e0929cf136c6c26a6774338be7eb9d140a94223f56e3339b2f80", size = 328461, upload-time = "2025-03-31T15:41:38.783Z" }, + { url = "https://files.pythonhosted.org/packages/04/77/5a4d5367eaabff85977fb3f322616f24d29d70d567fc0ea4f927317e81bd/jellyfish-1.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:baa1e44244cba9da6d67a50d3076dd7567e3b91caa9887bb68e20f321e0d2500", size = 325248, upload-time = "2025-03-31T15:41:42.344Z" }, + { url = "https://files.pythonhosted.org/packages/51/3d/c27b3ee999063caba206cf2f21542fe19d85e2d4ebe739e76a02b621a084/jellyfish-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65082288f76b3821e5cfeae6c2290621f9e8eff75e3fe2d90817dcd068c5bf36", size = 355959, upload-time = "2025-03-31T15:41:44.424Z" }, + { url = "https://files.pythonhosted.org/packages/51/de/874bb9fa8f1daf4723bdc9c8718951a4e0e1ca6361ff5c1a09b1ee76b55b/jellyfish-1.2.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4309d536a5427c008bab096fd38cb2d44c7e475c494b23f2554cfdcf8a19f7fb", size = 363956, upload-time = "2025-03-31T15:41:45.834Z" }, + { url = "https://files.pythonhosted.org/packages/48/08/fc3fd641dc09754a6986f3f00e625fd1aac89b1f012a1d4087c53391de64/jellyfish-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa0ac18693162b751bdd010a2c35136500a326b6a0bd0b18e6d973c524048ac7", size = 357026, upload-time = "2025-03-31T15:41:47.062Z" }, + { url = "https://files.pythonhosted.org/packages/7f/16/5466c0319a36f0b96f909e928e25f7ae311660903af57f382bf81a76bd45/jellyfish-1.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c19d70cfbfe4eb9c7c6a1df848cfa48f6e5166a3f23362a2c1d7a2e763674113", size = 533905, upload-time = "2025-03-31T15:41:48.188Z" }, + { url = "https://files.pythonhosted.org/packages/b3/70/0852e2b85b8114c564ad2d4d2d9e332feb84cef6719b7c197b74c0580a1c/jellyfish-1.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5616698941afc730aa6cc162a4686bda29aa8127d70bcb939321143b1170238a", size = 555397, upload-time = "2025-03-31T15:41:49.725Z" }, + { url = "https://files.pythonhosted.org/packages/39/f2/c54b7670ae67bb24fa87b34aa106385415a26a28c66731bbf4db520aea09/jellyfish-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b28ad8da20561f07ca4bf1297bd5519d8cd947b8b5593e00cc7ceb255b2a1d84", size = 527740, upload-time = "2025-03-31T15:41:51.875Z" }, + { url = "https://files.pythonhosted.org/packages/c7/bf/b0d88b6dab19789e5893064f83eb6a0b15498f46a887fcfa3a614f962d0a/jellyfish-1.2.0-cp310-cp310-win32.whl", hash = "sha256:6ec6db8301bf91de85ee5084a44f0b5d399cc030c86910730d5ae69f1e712438", size = 212500, upload-time = "2025-03-31T15:41:53.454Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b9/a252acda71bd81314d43397f084eec6c2a58c69ca5afcb71ffe6941b6c66/jellyfish-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:8ed2393f6d0c7e8ec53ab0627dc81e1613bc2e76a9c30332197d0a1df5e39356", size = 217140, upload-time = "2025-03-31T15:41:54.662Z" }, + { url = "https://files.pythonhosted.org/packages/30/eb/17ca88570c3ac4144101d614cddbccd1effc25f812cbc4ab8ad15b75730e/jellyfish-1.2.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b4f8ff3cda0e00f6f62fe98ffce28bd7f21d1d55875470f8275a2fdbd84cfb6a", size = 328511, upload-time = "2025-03-31T15:41:55.791Z" }, + { url = "https://files.pythonhosted.org/packages/1e/9a/521cbf0b77e86b2b3cda2b42b1afaf3498d4cc16b4240c6ff5b8941d8966/jellyfish-1.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:792cb481816626396892bccf53643ccc55a7f7c2b129de61360d01044a539afd", size = 325221, upload-time = "2025-03-31T15:41:57.064Z" }, + { url = "https://files.pythonhosted.org/packages/74/a0/344f432fc8a730dd896446164ed0843e388ed676c632536f6d1b1746c0af/jellyfish-1.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ca2c84d3aaeea4bd7c9bdb174229789e69c7dd58916b47813f52db3a1b62495", size = 355848, upload-time = "2025-03-31T15:41:58.554Z" }, + { url = "https://files.pythonhosted.org/packages/9f/8c/0fadfebdab24b7095531828e2757753525fa835a415c2a6694de9dae2339/jellyfish-1.2.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3ebc962fd90b2dcb33eb308e70c3a356a931c4b10c76d8d9d63df1d5dac42be4", size = 364054, upload-time = "2025-03-31T15:41:59.654Z" }, + { url = "https://files.pythonhosted.org/packages/ba/2b/e6ce825f2ae5638b7c6f8dfa675051424fcb45960a2759b332fd6be6dcb2/jellyfish-1.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0d765888bf186b75bf16b3d9a1b7f088f5f5ccbf62b414c25d92b404aad9c2a", size = 356926, upload-time = "2025-03-31T15:42:00.808Z" }, + { url = "https://files.pythonhosted.org/packages/45/4a/64e9f022df383651adb0b80a3473d31bf34f8ae79c9c27cea0a964ea008e/jellyfish-1.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:85c5eca0d56241d07a0a89f2896bc7d1ec66ee72ffa801847c70f404b0214fad", size = 533845, upload-time = "2025-03-31T15:42:02.264Z" }, + { url = "https://files.pythonhosted.org/packages/0a/d6/11178c93e59fad2ac9d1dbc750bc4f8d637a5e780ae8b4fd53b3d740b599/jellyfish-1.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:13d7d925760bd8c3fd8831fcc0ad5a32ceae82c66e8aa19df45082afe5c4be2a", size = 555528, upload-time = "2025-03-31T15:42:04.192Z" }, + { url = "https://files.pythonhosted.org/packages/e6/32/5be368336b901f792d137e1771e8446b102e6b6dbb5f82a2a92ef9467f0d/jellyfish-1.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ccc330b6104c87e22dbb22c2578abcf0e36d1346c1810eec3f67571089b36874", size = 527595, upload-time = "2025-03-31T15:42:05.361Z" }, + { url = "https://files.pythonhosted.org/packages/67/b2/6df2229e03f273f9b24cedea3174f5cb58b7d2856b8778913f4d44423f3d/jellyfish-1.2.0-cp311-cp311-win32.whl", hash = "sha256:75d131a51202e679b653507f99634bc13c4aa6a4afabe06a1c3d200f72e18b9b", size = 212604, upload-time = "2025-03-31T15:42:06.485Z" }, + { url = "https://files.pythonhosted.org/packages/9a/54/f1dca498a808e427374d3bd81832045f9cfbbecafbc7f49461a6425dfd0a/jellyfish-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:63f58a0a7c9c0bb9a69562d2b9dd1a3f6729e94b0dcb6adf54b45b4da853eb94", size = 217095, upload-time = "2025-03-31T15:42:07.627Z" }, + { url = "https://files.pythonhosted.org/packages/4a/d5/89424092e3d1e6948eb215fb1f58126fc8090989475f6cbc6545a0eae72c/jellyfish-1.2.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:088c9b7e7077802ce2254b876486ae3b49d81f4f07f6c692c612ba40e1a42177", size = 326154, upload-time = "2025-03-31T15:42:08.819Z" }, + { url = "https://files.pythonhosted.org/packages/91/af/881ef6fb6e2e534b7383c6ace369485e1c285dc70b9bab54e35796d4f1fd/jellyfish-1.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:393664438fbb98886f9c97675179d4b552b68c3d0099d4df3cdec6412deaeea0", size = 322983, upload-time = "2025-03-31T15:42:09.942Z" }, + { url = "https://files.pythonhosted.org/packages/1e/ee/d73ac46c3ad0f1d8b28de452b117080bab7d7a3565a05f1b34a5b6085f4e/jellyfish-1.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a54a83905596dd712948b6af7fccc2b28d37624bfc9eab4868518c3f8106c739", size = 355339, upload-time = "2025-03-31T15:42:11.04Z" }, + { url = "https://files.pythonhosted.org/packages/e4/1a/8952b21f9b52931c5997dc2d24b2a1660d76bb34aa69460b0d4e126501a9/jellyfish-1.2.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e2f68cdb689b59653fa70345c8fcb09bfee12d34c0f7ae223ce70fa5175cb2ee", size = 363903, upload-time = "2025-03-31T15:42:12.164Z" }, + { url = "https://files.pythonhosted.org/packages/25/df/bdeb876920dc26405e90a6abf014eff5a1892652a7875733ed0e91a0e424/jellyfish-1.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:019542af342973c537275b289c1e891fb2b62b011bfdb68c816da4527477b74d", size = 355931, upload-time = "2025-03-31T15:42:14.108Z" }, + { url = "https://files.pythonhosted.org/packages/dd/c3/cb05e3d092eb929d2043e4945d172f30781321d90b198a05316b8dfb97df/jellyfish-1.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:079ec6fceb5336e7c2f99b43ee035f85b39022db897c70e736439ed1d4fc8462", size = 533430, upload-time = "2025-03-31T15:42:15.559Z" }, + { url = "https://files.pythonhosted.org/packages/34/a0/af60a3d7ec0d7f537dd32efb485ed7969c0d8b3856cd3cc7445fa7b0bc3d/jellyfish-1.2.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a5ddd20e6d87c7dc173717ffe0df0bba50aa0b0c51e3d57d6cce1706ea6a1167", size = 554656, upload-time = "2025-03-31T15:42:16.733Z" }, + { url = "https://files.pythonhosted.org/packages/8f/db/92026263a56dea6751d9935a4c41c78f5561aa49c6b20e068389b25e6bfb/jellyfish-1.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:08a1a3f6adc033eb3735a8ba121188a5d3fdc6630eec6a946c30260c1ac680ac", size = 526659, upload-time = "2025-03-31T15:42:17.864Z" }, + { url = "https://files.pythonhosted.org/packages/e6/4e/c8c546a422090eb75c232454465aefb49e1030fad043a99a73ba12f80fee/jellyfish-1.2.0-cp312-cp312-win32.whl", hash = "sha256:65ec39cfed29e475df33c9d7fc70d76eb39ce6dfb7fedf19599caff497a9b3c7", size = 212397, upload-time = "2025-03-31T15:42:19.056Z" }, + { url = "https://files.pythonhosted.org/packages/90/6d/5770b7fb1767c12559aabe2bf5f629bee8d738dbe110301c14aa276d2c8a/jellyfish-1.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:199baa59412723ef76126303fc236728b2613a4723fba83eede942c89e1dad1c", size = 216558, upload-time = "2025-03-31T15:42:20.173Z" }, + { url = "https://files.pythonhosted.org/packages/f0/4e/2f10011b5a80c56bb0f2775ee7283a3290fb9ec4e67c48c0342671a6d6e0/jellyfish-1.2.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:8b995bdf97d43cdca1e6bd5375f351bcb85c7f5e8760fe4a28c63eb0e6104075", size = 325372, upload-time = "2025-03-31T15:42:21.563Z" }, + { url = "https://files.pythonhosted.org/packages/f8/7e/e15034422abf21e28b43155d21f4e34ae7349fad6c682be12c739d79119b/jellyfish-1.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:559c1d6f17ba51639843b958a0d57ece5c4155e6b820c4acb3f3437437625ef3", size = 322333, upload-time = "2025-03-31T15:42:23.015Z" }, + { url = "https://files.pythonhosted.org/packages/0b/62/cdb56ed6641c5a23bb00c775ea54108423b40d2376bed186455cc39f4a0b/jellyfish-1.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4439f4066ccc5dd6a7a15cb06941f5150bab646201e9e014a7d34d65cbe89fe", size = 354567, upload-time = "2025-03-31T15:42:24.22Z" }, + { url = "https://files.pythonhosted.org/packages/e0/97/47830ff857307936313e345010cf7626e7b3a233549cfc258c7342553de4/jellyfish-1.2.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dbf866d2b967fd2d5380134fdcb47d4f113e24d659b46c38e55da80c215d2042", size = 363379, upload-time = "2025-03-31T15:42:25.407Z" }, + { url = "https://files.pythonhosted.org/packages/8e/95/4e3d5bac918aa7b0e1cebff39822add0844dbfc433870949dccc3df8aae3/jellyfish-1.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9290b82276bba1941ad0f98226f51b43aeef7bdedb927b9266516b4519b9012", size = 355215, upload-time = "2025-03-31T15:42:26.695Z" }, + { url = "https://files.pythonhosted.org/packages/6e/2f/1d7aa3b7dc3d7e6a7f9e832a98440d14641670394c11718f7584dab434b2/jellyfish-1.2.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:052345ded2b00104a50acbab35c671efe06f40790202f6a2fc279ad645f31ab2", size = 532669, upload-time = "2025-03-31T15:42:27.806Z" }, + { url = "https://files.pythonhosted.org/packages/f6/0e/d527f9425e9462463e3b0ae748ec39ec5a2ebaa829725ca8c09f8753e364/jellyfish-1.2.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:465dcf8b17162e3dae2cae0072b22ea9637e6ce8ddd8294181758437cd9c0673", size = 554223, upload-time = "2025-03-31T15:42:29.362Z" }, + { url = "https://files.pythonhosted.org/packages/04/71/533b48054f1ddab7d9b7ad3833a87963200c7aef7ce81e082379da6d1264/jellyfish-1.2.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ae5f2e3c5ef14cb5b86afe7ed4078e504f75dd61ca9d9560bef597f9d2237c63", size = 526103, upload-time = "2025-03-31T15:42:30.528Z" }, + { url = "https://files.pythonhosted.org/packages/f4/d7/6c5ce80088495b7bb002931d7d0a313143b45fa10e826f11aadd4a97ccdb/jellyfish-1.2.0-cp313-cp313-win32.whl", hash = "sha256:13ee212b6fa294a1b6306693a1553b760d876780e757b9f016010748fe811b4d", size = 212179, upload-time = "2025-03-31T15:42:31.628Z" }, + { url = "https://files.pythonhosted.org/packages/40/aa/332fd282668a353570bdad56d65f526bc28ab73da1a3dd99e670af687186/jellyfish-1.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:c8089e918ddb1abae946e92d053f646a7f686d0d051ef69cdfaa28b37352bbdf", size = 216066, upload-time = "2025-03-31T15:42:32.75Z" }, + { url = "https://files.pythonhosted.org/packages/a3/a3/ac72cdab59f0eb52eecda5f739ef69fa61ed6d5f7b0129043219e9ce8b58/jellyfish-1.2.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3c0d9d4136341c34ed0fb3fb406801d7a2724a1fa4996577822bc5e5b27870b4", size = 330579, upload-time = "2025-03-31T15:42:46.677Z" }, + { url = "https://files.pythonhosted.org/packages/3d/77/9a7734d7afb5ee349be7a627821d2bf5e84f2469010c9628d4bb21c813ec/jellyfish-1.2.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:36e53729ac0bd387c8f7fd60c8727e6784113976058d8aa2f62398fcdfe209f1", size = 326878, upload-time = "2025-03-31T15:42:48.154Z" }, + { url = "https://files.pythonhosted.org/packages/ba/38/9d1d0c7288a35ed7a9bef87fab745df2740222bed67677c270bae65ce21f/jellyfish-1.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10b178b8351e90e463d937e53c8b5525627a0bb2ca6f7e49ac7452b0608a1020", size = 357373, upload-time = "2025-03-31T15:42:49.453Z" }, + { url = "https://files.pythonhosted.org/packages/93/90/987343f6e43757731fbd62e5e74cfa0c519ad07faef2ff9c31c45386a42c/jellyfish-1.2.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e79225fba34bb082d2f21fa5cd7dc015c856ff04b8340e98ce122ab71a445cad", size = 365456, upload-time = "2025-03-31T15:42:51.136Z" }, + { url = "https://files.pythonhosted.org/packages/6d/12/0834bedcbc107bc17582787d8cd6b6ef21b0290e2847212d1997ec3353bc/jellyfish-1.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18a1ea2d395a4c9c00224b3abd57b73bd2cb4ca17fc6e2024c8433b31e1b1061", size = 358547, upload-time = "2025-03-31T15:42:52.478Z" }, + { url = "https://files.pythonhosted.org/packages/99/5a/5518f6f8c57c75fffba0163f06e3c0ce5df7ef6f40a1a0affb78de767881/jellyfish-1.2.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:b27ff486175b9c8fecdc9147c7dde1d835675bd76df12c1521f378a2fab70493", size = 535731, upload-time = "2025-03-31T15:42:53.667Z" }, + { url = "https://files.pythonhosted.org/packages/25/87/21376b582989cc9103fea496690ce8651fc3587c0c9a546a99cced2d9d0f/jellyfish-1.2.0-pp310-pypy310_pp73-musllinux_1_1_i686.whl", hash = "sha256:4b6b1109174e6ae780f6c2b8454b2fcfc7efeb8fae767f757c481ccca16fb842", size = 557248, upload-time = "2025-03-31T15:42:54.862Z" }, + { url = "https://files.pythonhosted.org/packages/81/ff/8f6d536cb1afda322f989d294cbfb9fa22aa2493e0bbe8b62a35f87e7f0e/jellyfish-1.2.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dfb4e76c2b6c3e94ea3778510c94609893ddc7172255838b3221eba1ec9aa5cc", size = 529209, upload-time = "2025-03-31T15:42:56.062Z" }, + { url = "https://files.pythonhosted.org/packages/1a/39/99494ab43d6127d7e2bd415c34b37e89fe16fb796a872b9c272558729ca0/jellyfish-1.2.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:07384e33e5f9bfd3d1356cf73d94388af295ed8f196a1d9f09bc381c5ea79be8", size = 330535, upload-time = "2025-03-31T15:42:57.222Z" }, + { url = "https://files.pythonhosted.org/packages/eb/5f/7b3bcb94a3fef83b4119608e40ecc70a1dd97cebc7a0122847b85593b9f8/jellyfish-1.2.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:03754194fc2f5cf65136f2b5f2aeacf48a805ddf21f4ff9f1a6cffc67756d937", size = 326847, upload-time = "2025-03-31T15:42:58.338Z" }, + { url = "https://files.pythonhosted.org/packages/28/96/9aed3d95e50d41d2fa9fe64d88e4d87927cdd56a1a399cbd0d31cc2ef870/jellyfish-1.2.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57a0c408c588c4477bdcd82c0c1c33f08900aca5c2dfc9d5e78f2e0919294a68", size = 357277, upload-time = "2025-03-31T15:42:59.975Z" }, + { url = "https://files.pythonhosted.org/packages/4f/ac/e91fe4f5742902d4ce2b39c18553c2939c3d0b713b8aa5a43127e371cdc2/jellyfish-1.2.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72062c9772ff672535463954828e9921fb1bf1d63c66602db2956567e9e50aa8", size = 365524, upload-time = "2025-03-31T15:43:01.595Z" }, + { url = "https://files.pythonhosted.org/packages/e7/4e/a94fbc02e7f9781e354ddf8eab01cb9acdf437933cf83c7c7cb5a49f9a96/jellyfish-1.2.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb3b464faeb8e4f4f6f7987fbd3f5de759fc0d460bbe4768b446e3f1c003026a", size = 358459, upload-time = "2025-03-31T15:43:02.917Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d7/05a8608e26f62c2ea2e33bba9670d39995231f307b12eb0692d6e091a607/jellyfish-1.2.0-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:33c5d80209b278807a770a463f39d0b6a3f95dacf9a64fd322ad4add63a52516", size = 535658, upload-time = "2025-03-31T15:43:04.039Z" }, + { url = "https://files.pythonhosted.org/packages/71/ac/bb1c3b58f7882b0c26e3f0cc2d2333fe5ed283f95ea0bc0e767cc31bf9d8/jellyfish-1.2.0-pp311-pypy311_pp73-musllinux_1_1_i686.whl", hash = "sha256:0787a5fef60aa838732f325064cc4401425e450023bb8fc8d3b2bd2ee75df57d", size = 557211, upload-time = "2025-03-31T15:43:05.268Z" }, + { url = "https://files.pythonhosted.org/packages/86/f2/28437297b00e64edb74a7c2dd05b50e905a5a8bb1ec72b519a70507a7762/jellyfish-1.2.0-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dee4cc60f2b342f3f62784787f1ba811e505b9a8d8f68cc7505d496c563143b5", size = 529113, upload-time = "2025-03-31T15:43:06.478Z" }, +] + +[[package]] +name = "mccabe" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", size = 9658, upload-time = "2022-01-24T01:14:51.113Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350, upload-time = "2022-01-24T01:14:49.62Z" }, +] + +[[package]] +name = "networkx" +version = "3.4.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fd/1d/06475e1cd5264c0b870ea2cc6fdb3e37177c1e565c43f56ff17a10e3937f/networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1", size = 2151368, upload-time = "2024-10-21T12:39:38.695Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/54/dd730b32ea14ea797530a4479b2ed46a6fb250f682a9cfb997e968bf0261/networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f", size = 1723263, upload-time = "2024-10-21T12:39:36.247Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload-time = "2025-05-17T21:31:19.36Z" }, + { url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload-time = "2025-05-17T21:31:41.087Z" }, + { url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload-time = "2025-05-17T21:31:50.072Z" }, + { url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload-time = "2025-05-17T21:32:01.712Z" }, + { url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload-time = "2025-05-17T21:32:23.332Z" }, + { url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload-time = "2025-05-17T21:32:47.991Z" }, + { url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload-time = "2025-05-17T21:33:11.728Z" }, + { url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload-time = "2025-05-17T21:33:39.139Z" }, + { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload-time = "2025-05-17T21:33:50.273Z" }, + { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload-time = "2025-05-17T21:34:09.135Z" }, + { url = "https://files.pythonhosted.org/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348, upload-time = "2025-05-17T21:34:39.648Z" }, + { url = "https://files.pythonhosted.org/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362, upload-time = "2025-05-17T21:35:01.241Z" }, + { url = "https://files.pythonhosted.org/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103, upload-time = "2025-05-17T21:35:10.622Z" }, + { url = "https://files.pythonhosted.org/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382, upload-time = "2025-05-17T21:35:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462, upload-time = "2025-05-17T21:35:42.174Z" }, + { url = "https://files.pythonhosted.org/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618, upload-time = "2025-05-17T21:36:06.711Z" }, + { url = "https://files.pythonhosted.org/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511, upload-time = "2025-05-17T21:36:29.965Z" }, + { url = "https://files.pythonhosted.org/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783, upload-time = "2025-05-17T21:36:56.883Z" }, + { url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506, upload-time = "2025-05-17T21:37:07.368Z" }, + { url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190, upload-time = "2025-05-17T21:37:26.213Z" }, + { url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828, upload-time = "2025-05-17T21:37:56.699Z" }, + { url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006, upload-time = "2025-05-17T21:38:18.291Z" }, + { url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765, upload-time = "2025-05-17T21:38:27.319Z" }, + { url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736, upload-time = "2025-05-17T21:38:38.141Z" }, + { url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719, upload-time = "2025-05-17T21:38:58.433Z" }, + { url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072, upload-time = "2025-05-17T21:39:22.638Z" }, + { url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213, upload-time = "2025-05-17T21:39:45.865Z" }, + { url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632, upload-time = "2025-05-17T21:40:13.331Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532, upload-time = "2025-05-17T21:43:46.099Z" }, + { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885, upload-time = "2025-05-17T21:44:05.145Z" }, + { url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467, upload-time = "2025-05-17T21:40:44Z" }, + { url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144, upload-time = "2025-05-17T21:41:05.695Z" }, + { url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217, upload-time = "2025-05-17T21:41:15.903Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014, upload-time = "2025-05-17T21:41:27.321Z" }, + { url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935, upload-time = "2025-05-17T21:41:49.738Z" }, + { url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122, upload-time = "2025-05-17T21:42:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143, upload-time = "2025-05-17T21:42:37.464Z" }, + { url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260, upload-time = "2025-05-17T21:43:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225, upload-time = "2025-05-17T21:43:16.254Z" }, + { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374, upload-time = "2025-05-17T21:43:35.479Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pycodestyle" +version = "2.13.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/04/6e/1f4a62078e4d95d82367f24e685aef3a672abfd27d1a868068fed4ed2254/pycodestyle-2.13.0.tar.gz", hash = "sha256:c8415bf09abe81d9c7f872502a6eee881fbe85d8763dd5b9924bb0a01d67efae", size = 39312, upload-time = "2025-03-29T17:33:30.669Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/be/b00116df1bfb3e0bb5b45e29d604799f7b91dd861637e4d448b4e09e6a3e/pycodestyle-2.13.0-py2.py3-none-any.whl", hash = "sha256:35863c5974a271c7a726ed228a14a4f6daf49df369d8c50cd9a6f58a5e143ba9", size = 31424, upload-time = "2025-03-29T17:33:29.405Z" }, +] + +[[package]] +name = "pyflakes" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/af/cc/1df338bd7ed1fa7c317081dcf29bf2f01266603b301e6858856d346a12b3/pyflakes-3.3.2.tar.gz", hash = "sha256:6dfd61d87b97fba5dcfaaf781171ac16be16453be6d816147989e7f6e6a9576b", size = 64175, upload-time = "2025-03-31T13:21:20.34Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/15/40/b293a4fa769f3b02ab9e387c707c4cbdc34f073f945de0386107d4e669e6/pyflakes-3.3.2-py2.py3-none-any.whl", hash = "sha256:5039c8339cbb1944045f4ee5466908906180f13cc99cc9949348d10f82a5c32a", size = 63164, upload-time = "2025-03-31T13:21:18.503Z" }, +] + +[[package]] +name = "pytest" +version = "8.3.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891, upload-time = "2025-03-02T12:54:54.503Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634, upload-time = "2025-03-02T12:54:52.069Z" }, +] + +[[package]] +name = "pytest-runner" +version = "6.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/7d/60976d532519c3a0b41e06a59ad60949e2be1af937cf02738fec91bfd808/pytest-runner-6.0.1.tar.gz", hash = "sha256:70d4739585a7008f37bf4933c013fdb327b8878a5a69fcbb3316c88882f0f49b", size = 16056, upload-time = "2023-12-04T01:03:30.835Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/2b/73982c02d28538b6a1182c0a2faf764ca6a76a6dbe89a69288184051a67b/pytest_runner-6.0.1-py3-none-any.whl", hash = "sha256:ea326ed6f6613992746062362efab70212089a4209c08d67177b3df1c52cd9f2", size = 7186, upload-time = "2023-12-04T01:03:28.706Z" }, +] + +[[package]] +name = "regex" +version = "2024.11.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/5f/bd69653fbfb76cf8604468d3b4ec4c403197144c7bfe0e6a5fc9e02a07cb/regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", size = 399494, upload-time = "2024-11-06T20:12:31.635Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/3c/4651f6b130c6842a8f3df82461a8950f923925db8b6961063e82744bddcc/regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91", size = 482674, upload-time = "2024-11-06T20:08:57.575Z" }, + { url = "https://files.pythonhosted.org/packages/15/51/9f35d12da8434b489c7b7bffc205c474a0a9432a889457026e9bc06a297a/regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0", size = 287684, upload-time = "2024-11-06T20:08:59.787Z" }, + { url = "https://files.pythonhosted.org/packages/bd/18/b731f5510d1b8fb63c6b6d3484bfa9a59b84cc578ac8b5172970e05ae07c/regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e", size = 284589, upload-time = "2024-11-06T20:09:01.896Z" }, + { url = "https://files.pythonhosted.org/packages/78/a2/6dd36e16341ab95e4c6073426561b9bfdeb1a9c9b63ab1b579c2e96cb105/regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde", size = 782511, upload-time = "2024-11-06T20:09:04.062Z" }, + { url = "https://files.pythonhosted.org/packages/1b/2b/323e72d5d2fd8de0d9baa443e1ed70363ed7e7b2fb526f5950c5cb99c364/regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e", size = 821149, upload-time = "2024-11-06T20:09:06.237Z" }, + { url = "https://files.pythonhosted.org/packages/90/30/63373b9ea468fbef8a907fd273e5c329b8c9535fee36fc8dba5fecac475d/regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2", size = 809707, upload-time = "2024-11-06T20:09:07.715Z" }, + { url = "https://files.pythonhosted.org/packages/f2/98/26d3830875b53071f1f0ae6d547f1d98e964dd29ad35cbf94439120bb67a/regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf", size = 781702, upload-time = "2024-11-06T20:09:10.101Z" }, + { url = "https://files.pythonhosted.org/packages/87/55/eb2a068334274db86208ab9d5599ffa63631b9f0f67ed70ea7c82a69bbc8/regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c", size = 771976, upload-time = "2024-11-06T20:09:11.566Z" }, + { url = "https://files.pythonhosted.org/packages/74/c0/be707bcfe98254d8f9d2cff55d216e946f4ea48ad2fd8cf1428f8c5332ba/regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86", size = 697397, upload-time = "2024-11-06T20:09:13.119Z" }, + { url = "https://files.pythonhosted.org/packages/49/dc/bb45572ceb49e0f6509f7596e4ba7031f6819ecb26bc7610979af5a77f45/regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67", size = 768726, upload-time = "2024-11-06T20:09:14.85Z" }, + { url = "https://files.pythonhosted.org/packages/5a/db/f43fd75dc4c0c2d96d0881967897926942e935d700863666f3c844a72ce6/regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d", size = 775098, upload-time = "2024-11-06T20:09:16.504Z" }, + { url = "https://files.pythonhosted.org/packages/99/d7/f94154db29ab5a89d69ff893159b19ada89e76b915c1293e98603d39838c/regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2", size = 839325, upload-time = "2024-11-06T20:09:18.698Z" }, + { url = "https://files.pythonhosted.org/packages/f7/17/3cbfab1f23356fbbf07708220ab438a7efa1e0f34195bf857433f79f1788/regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008", size = 843277, upload-time = "2024-11-06T20:09:21.725Z" }, + { url = "https://files.pythonhosted.org/packages/7e/f2/48b393b51900456155de3ad001900f94298965e1cad1c772b87f9cfea011/regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62", size = 773197, upload-time = "2024-11-06T20:09:24.092Z" }, + { url = "https://files.pythonhosted.org/packages/45/3f/ef9589aba93e084cd3f8471fded352826dcae8489b650d0b9b27bc5bba8a/regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e", size = 261714, upload-time = "2024-11-06T20:09:26.36Z" }, + { url = "https://files.pythonhosted.org/packages/42/7e/5f1b92c8468290c465fd50c5318da64319133231415a8aa6ea5ab995a815/regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519", size = 274042, upload-time = "2024-11-06T20:09:28.762Z" }, + { url = "https://files.pythonhosted.org/packages/58/58/7e4d9493a66c88a7da6d205768119f51af0f684fe7be7bac8328e217a52c/regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638", size = 482669, upload-time = "2024-11-06T20:09:31.064Z" }, + { url = "https://files.pythonhosted.org/packages/34/4c/8f8e631fcdc2ff978609eaeef1d6994bf2f028b59d9ac67640ed051f1218/regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7", size = 287684, upload-time = "2024-11-06T20:09:32.915Z" }, + { url = "https://files.pythonhosted.org/packages/c5/1b/f0e4d13e6adf866ce9b069e191f303a30ab1277e037037a365c3aad5cc9c/regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20", size = 284589, upload-time = "2024-11-06T20:09:35.504Z" }, + { url = "https://files.pythonhosted.org/packages/25/4d/ab21047f446693887f25510887e6820b93f791992994f6498b0318904d4a/regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114", size = 792121, upload-time = "2024-11-06T20:09:37.701Z" }, + { url = "https://files.pythonhosted.org/packages/45/ee/c867e15cd894985cb32b731d89576c41a4642a57850c162490ea34b78c3b/regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3", size = 831275, upload-time = "2024-11-06T20:09:40.371Z" }, + { url = "https://files.pythonhosted.org/packages/b3/12/b0f480726cf1c60f6536fa5e1c95275a77624f3ac8fdccf79e6727499e28/regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f", size = 818257, upload-time = "2024-11-06T20:09:43.059Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ce/0d0e61429f603bac433910d99ef1a02ce45a8967ffbe3cbee48599e62d88/regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0", size = 792727, upload-time = "2024-11-06T20:09:48.19Z" }, + { url = "https://files.pythonhosted.org/packages/e4/c1/243c83c53d4a419c1556f43777ccb552bccdf79d08fda3980e4e77dd9137/regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55", size = 780667, upload-time = "2024-11-06T20:09:49.828Z" }, + { url = "https://files.pythonhosted.org/packages/c5/f4/75eb0dd4ce4b37f04928987f1d22547ddaf6c4bae697623c1b05da67a8aa/regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89", size = 776963, upload-time = "2024-11-06T20:09:51.819Z" }, + { url = "https://files.pythonhosted.org/packages/16/5d/95c568574e630e141a69ff8a254c2f188b4398e813c40d49228c9bbd9875/regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d", size = 784700, upload-time = "2024-11-06T20:09:53.982Z" }, + { url = "https://files.pythonhosted.org/packages/8e/b5/f8495c7917f15cc6fee1e7f395e324ec3e00ab3c665a7dc9d27562fd5290/regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34", size = 848592, upload-time = "2024-11-06T20:09:56.222Z" }, + { url = "https://files.pythonhosted.org/packages/1c/80/6dd7118e8cb212c3c60b191b932dc57db93fb2e36fb9e0e92f72a5909af9/regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d", size = 852929, upload-time = "2024-11-06T20:09:58.642Z" }, + { url = "https://files.pythonhosted.org/packages/11/9b/5a05d2040297d2d254baf95eeeb6df83554e5e1df03bc1a6687fc4ba1f66/regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45", size = 781213, upload-time = "2024-11-06T20:10:00.867Z" }, + { url = "https://files.pythonhosted.org/packages/26/b7/b14e2440156ab39e0177506c08c18accaf2b8932e39fb092074de733d868/regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9", size = 261734, upload-time = "2024-11-06T20:10:03.361Z" }, + { url = "https://files.pythonhosted.org/packages/80/32/763a6cc01d21fb3819227a1cc3f60fd251c13c37c27a73b8ff4315433a8e/regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60", size = 274052, upload-time = "2024-11-06T20:10:05.179Z" }, + { url = "https://files.pythonhosted.org/packages/ba/30/9a87ce8336b172cc232a0db89a3af97929d06c11ceaa19d97d84fa90a8f8/regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a", size = 483781, upload-time = "2024-11-06T20:10:07.07Z" }, + { url = "https://files.pythonhosted.org/packages/01/e8/00008ad4ff4be8b1844786ba6636035f7ef926db5686e4c0f98093612add/regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9", size = 288455, upload-time = "2024-11-06T20:10:09.117Z" }, + { url = "https://files.pythonhosted.org/packages/60/85/cebcc0aff603ea0a201667b203f13ba75d9fc8668fab917ac5b2de3967bc/regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2", size = 284759, upload-time = "2024-11-06T20:10:11.155Z" }, + { url = "https://files.pythonhosted.org/packages/94/2b/701a4b0585cb05472a4da28ee28fdfe155f3638f5e1ec92306d924e5faf0/regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4", size = 794976, upload-time = "2024-11-06T20:10:13.24Z" }, + { url = "https://files.pythonhosted.org/packages/4b/bf/fa87e563bf5fee75db8915f7352e1887b1249126a1be4813837f5dbec965/regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577", size = 833077, upload-time = "2024-11-06T20:10:15.37Z" }, + { url = "https://files.pythonhosted.org/packages/a1/56/7295e6bad94b047f4d0834e4779491b81216583c00c288252ef625c01d23/regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3", size = 823160, upload-time = "2024-11-06T20:10:19.027Z" }, + { url = "https://files.pythonhosted.org/packages/fb/13/e3b075031a738c9598c51cfbc4c7879e26729c53aa9cca59211c44235314/regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e", size = 796896, upload-time = "2024-11-06T20:10:21.85Z" }, + { url = "https://files.pythonhosted.org/packages/24/56/0b3f1b66d592be6efec23a795b37732682520b47c53da5a32c33ed7d84e3/regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe", size = 783997, upload-time = "2024-11-06T20:10:24.329Z" }, + { url = "https://files.pythonhosted.org/packages/f9/a1/eb378dada8b91c0e4c5f08ffb56f25fcae47bf52ad18f9b2f33b83e6d498/regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e", size = 781725, upload-time = "2024-11-06T20:10:28.067Z" }, + { url = "https://files.pythonhosted.org/packages/83/f2/033e7dec0cfd6dda93390089864732a3409246ffe8b042e9554afa9bff4e/regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29", size = 789481, upload-time = "2024-11-06T20:10:31.612Z" }, + { url = "https://files.pythonhosted.org/packages/83/23/15d4552ea28990a74e7696780c438aadd73a20318c47e527b47a4a5a596d/regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39", size = 852896, upload-time = "2024-11-06T20:10:34.054Z" }, + { url = "https://files.pythonhosted.org/packages/e3/39/ed4416bc90deedbfdada2568b2cb0bc1fdb98efe11f5378d9892b2a88f8f/regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51", size = 860138, upload-time = "2024-11-06T20:10:36.142Z" }, + { url = "https://files.pythonhosted.org/packages/93/2d/dd56bb76bd8e95bbce684326302f287455b56242a4f9c61f1bc76e28360e/regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad", size = 787692, upload-time = "2024-11-06T20:10:38.394Z" }, + { url = "https://files.pythonhosted.org/packages/0b/55/31877a249ab7a5156758246b9c59539abbeba22461b7d8adc9e8475ff73e/regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54", size = 262135, upload-time = "2024-11-06T20:10:40.367Z" }, + { url = "https://files.pythonhosted.org/packages/38/ec/ad2d7de49a600cdb8dd78434a1aeffe28b9d6fc42eb36afab4a27ad23384/regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b", size = 273567, upload-time = "2024-11-06T20:10:43.467Z" }, + { url = "https://files.pythonhosted.org/packages/90/73/bcb0e36614601016552fa9344544a3a2ae1809dc1401b100eab02e772e1f/regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84", size = 483525, upload-time = "2024-11-06T20:10:45.19Z" }, + { url = "https://files.pythonhosted.org/packages/0f/3f/f1a082a46b31e25291d830b369b6b0c5576a6f7fb89d3053a354c24b8a83/regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4", size = 288324, upload-time = "2024-11-06T20:10:47.177Z" }, + { url = "https://files.pythonhosted.org/packages/09/c9/4e68181a4a652fb3ef5099e077faf4fd2a694ea6e0f806a7737aff9e758a/regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0", size = 284617, upload-time = "2024-11-06T20:10:49.312Z" }, + { url = "https://files.pythonhosted.org/packages/fc/fd/37868b75eaf63843165f1d2122ca6cb94bfc0271e4428cf58c0616786dce/regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0", size = 795023, upload-time = "2024-11-06T20:10:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/c4/7c/d4cd9c528502a3dedb5c13c146e7a7a539a3853dc20209c8e75d9ba9d1b2/regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7", size = 833072, upload-time = "2024-11-06T20:10:52.926Z" }, + { url = "https://files.pythonhosted.org/packages/4f/db/46f563a08f969159c5a0f0e722260568425363bea43bb7ae370becb66a67/regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7", size = 823130, upload-time = "2024-11-06T20:10:54.828Z" }, + { url = "https://files.pythonhosted.org/packages/db/60/1eeca2074f5b87df394fccaa432ae3fc06c9c9bfa97c5051aed70e6e00c2/regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c", size = 796857, upload-time = "2024-11-06T20:10:56.634Z" }, + { url = "https://files.pythonhosted.org/packages/10/db/ac718a08fcee981554d2f7bb8402f1faa7e868c1345c16ab1ebec54b0d7b/regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3", size = 784006, upload-time = "2024-11-06T20:10:59.369Z" }, + { url = "https://files.pythonhosted.org/packages/c2/41/7da3fe70216cea93144bf12da2b87367590bcf07db97604edeea55dac9ad/regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07", size = 781650, upload-time = "2024-11-06T20:11:02.042Z" }, + { url = "https://files.pythonhosted.org/packages/a7/d5/880921ee4eec393a4752e6ab9f0fe28009435417c3102fc413f3fe81c4e5/regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e", size = 789545, upload-time = "2024-11-06T20:11:03.933Z" }, + { url = "https://files.pythonhosted.org/packages/dc/96/53770115e507081122beca8899ab7f5ae28ae790bfcc82b5e38976df6a77/regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6", size = 853045, upload-time = "2024-11-06T20:11:06.497Z" }, + { url = "https://files.pythonhosted.org/packages/31/d3/1372add5251cc2d44b451bd94f43b2ec78e15a6e82bff6a290ef9fd8f00a/regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4", size = 860182, upload-time = "2024-11-06T20:11:09.06Z" }, + { url = "https://files.pythonhosted.org/packages/ed/e3/c446a64984ea9f69982ba1a69d4658d5014bc7a0ea468a07e1a1265db6e2/regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d", size = 787733, upload-time = "2024-11-06T20:11:11.256Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f1/e40c8373e3480e4f29f2692bd21b3e05f296d3afebc7e5dcf21b9756ca1c/regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff", size = 262122, upload-time = "2024-11-06T20:11:13.161Z" }, + { url = "https://files.pythonhosted.org/packages/45/94/bc295babb3062a731f52621cdc992d123111282e291abaf23faa413443ea/regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a", size = 273545, upload-time = "2024-11-06T20:11:15Z" }, +] + +[[package]] +name = "segtok" +version = "1.5.11" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "regex" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0c/8a/1ae8e3deb805831933b63d58851ab41ff2472099e15511fc62039421ad70/segtok-1.5.11.tar.gz", hash = "sha256:8ab2dd44245bcbfec25b575dc4618473bbdf2af8c2649698cd5a370f42f3db23", size = 25244, upload-time = "2021-12-15T21:56:14.555Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dd/60/d384dbae5d4756e33f1750fa3472303de2c827011907a64e213e114d0556/segtok-1.5.11-py3-none-any.whl", hash = "sha256:910616b76198c3141b2772df530270d3b706e42ae69a5b30ef115c7bd5d1501a", size = 24332, upload-time = "2021-12-15T21:56:12.508Z" }, +] + +[[package]] +name = "tabulate" +version = "0.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/fe/802052aecb21e3797b8f7902564ab6ea0d60ff8ca23952079064155d1ae1/tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c", size = 81090, upload-time = "2022-10-06T17:21:48.54Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252, upload-time = "2022-10-06T17:21:44.262Z" }, +] + +[[package]] +name = "tomli" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload-time = "2024-11-27T22:37:54.956Z" }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload-time = "2024-11-27T22:37:56.698Z" }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload-time = "2024-11-27T22:37:57.63Z" }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload-time = "2024-11-27T22:37:59.344Z" }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload-time = "2024-11-27T22:38:00.429Z" }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload-time = "2024-11-27T22:38:02.094Z" }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload-time = "2024-11-27T22:38:03.206Z" }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload-time = "2024-11-27T22:38:04.217Z" }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload-time = "2024-11-27T22:38:05.908Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload-time = "2024-11-27T22:38:06.812Z" }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload-time = "2024-11-27T22:38:21.659Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload-time = "2024-11-27T22:38:22.693Z" }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload-time = "2024-11-27T22:38:24.367Z" }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload-time = "2024-11-27T22:38:26.081Z" }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload-time = "2024-11-27T22:38:27.921Z" }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload-time = "2024-11-27T22:38:29.591Z" }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload-time = "2024-11-27T22:38:30.639Z" }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload-time = "2024-11-27T22:38:31.702Z" }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload-time = "2024-11-27T22:38:32.837Z" }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload-time = "2024-11-27T22:38:34.455Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.13.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" }, +] + +[[package]] +name = "yake" +version = "0.6.0" +source = { editable = "." } +dependencies = [ + { name = "click" }, + { name = "jellyfish" }, + { name = "networkx" }, + { name = "numpy" }, + { name = "segtok" }, + { name = "tabulate" }, +] + +[package.optional-dependencies] +dev = [ + { name = "flake8" }, + { name = "pytest" }, + { name = "pytest-runner" }, +] + +[package.metadata] +requires-dist = [ + { name = "click", specifier = ">=6.0" }, + { name = "flake8", marker = "extra == 'dev'" }, + { name = "jellyfish" }, + { name = "networkx" }, + { name = "numpy", specifier = ">=1.23.5" }, + { name = "pytest", marker = "extra == 'dev'" }, + { name = "pytest-runner", marker = "extra == 'dev'" }, + { name = "segtok" }, + { name = "tabulate" }, +] +provides-extras = ["dev"] diff --git a/yake/Levenshtein.py b/yake/Levenshtein.py deleted file mode 100644 index 899d3bff..00000000 --- a/yake/Levenshtein.py +++ /dev/null @@ -1,39 +0,0 @@ -import numpy as np - -class Levenshtein(object): - - @staticmethod - def __ratio(distance, str_length): - return 1 - float(distance) / float(str_length) - - @staticmethod - def ratio(seq1, seq2): - str_distance = Levenshtein.distance(seq1,seq2) - str_length = max(len(seq1),len(seq2)) - return Levenshtein.__ratio(str_distance,str_length) - - @staticmethod - def distance(seq1, seq2): - size_x = len(seq1) + 1 - size_y = len(seq2) + 1 - matrix = np.zeros ((size_x, size_y)) - for x in range(size_x): - matrix [x, 0] = x - for y in range(size_y): - matrix [0, y] = y - - for x in range(1, size_x): - for y in range(1, size_y): - if seq1[x-1] == seq2[y-1]: - matrix [x,y] = min( - matrix[x-1, y] + 1, - matrix[x-1, y-1], - matrix[x, y-1] + 1 - ) - else: - matrix [x,y] = min( - matrix[x-1,y] + 1, - matrix[x-1,y-1] + 1, - matrix[x,y-1] + 1 - ) - return (matrix[size_x - 1, size_y - 1]) \ No newline at end of file diff --git a/yake/__init__.py b/yake/__init__.py index 911bc4b9..237be329 100644 --- a/yake/__init__.py +++ b/yake/__init__.py @@ -3,7 +3,8 @@ """Top-level package for yake.""" __author__ = """vitordouzi""" -__email__ = 'vitordouzi@gmail.com' -__version__ = '0.4.8' +__email__ = "vitordouzi@gmail.com" +__version__ = "0.4.8" + +from yake.core.yake import KeywordExtractor as KeywordExtractor -from yake.yake import KeywordExtractor diff --git a/yake/__pycache__/__init__.cpython-310.pyc b/yake/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..80f412fa Binary files /dev/null and b/yake/__pycache__/__init__.cpython-310.pyc differ diff --git a/yake/__pycache__/datarepresentation.cpython-310.pyc b/yake/__pycache__/datarepresentation.cpython-310.pyc new file mode 100644 index 00000000..10c70a2c Binary files /dev/null and b/yake/__pycache__/datarepresentation.cpython-310.pyc differ diff --git a/yake/__pycache__/highlight.cpython-310.pyc b/yake/__pycache__/highlight.cpython-310.pyc new file mode 100644 index 00000000..26edd14e Binary files /dev/null and b/yake/__pycache__/highlight.cpython-310.pyc differ diff --git a/yake/__pycache__/levenshtein.cpython-310.pyc b/yake/__pycache__/levenshtein.cpython-310.pyc new file mode 100644 index 00000000..7568c8b8 Binary files /dev/null and b/yake/__pycache__/levenshtein.cpython-310.pyc differ diff --git a/yake/__pycache__/yake.cpython-310.pyc b/yake/__pycache__/yake.cpython-310.pyc new file mode 100644 index 00000000..60ce8dd5 Binary files /dev/null and b/yake/__pycache__/yake.cpython-310.pyc differ diff --git a/yake/__pycache__/yake.cpython-312.pyc b/yake/__pycache__/yake.cpython-312.pyc new file mode 100644 index 00000000..08a019cf Binary files /dev/null and b/yake/__pycache__/yake.cpython-312.pyc differ diff --git a/yake/__pycache__/yakenew.cpython-312.pyc b/yake/__pycache__/yakenew.cpython-312.pyc new file mode 100644 index 00000000..9332d304 Binary files /dev/null and b/yake/__pycache__/yakenew.cpython-312.pyc differ diff --git a/yake/cli.py b/yake/cli.py index 5e3abee0..c85b0252 100644 --- a/yake/cli.py +++ b/yake/cli.py @@ -1,53 +1,116 @@ -# -*- coding: utf-8 -*- - -"""Console script for yake.""" +"""CLI para extração de palavras-chave utilizando YAKE!""" +import sys import click -import yake from tabulate import tabulate +import yake -@click.command() -@click.option("-ti",'--text_input', help='Input text, SURROUNDED by single quotes(\')', required=False) -@click.option("-i",'--input_file', help='Input file', required=False) -@click.option("-l",'--language', default="en", help='Language', required=False) - -@click.option('-n','--ngram-size', default=3, help='Max size of the ngram.', required=False, type=int) -@click.option('-df','--dedup-func', help='Deduplication function.', default='seqm', type=click.Choice(['leve', 'jaro', 'seqm']), required=False) -@click.option('-dl','--dedup-lim', type=float, help='Deduplication limiar.', default=.9, required=False) - -@click.option('-ws','--window-size', type=int, help='Window size.', default=1, required=False) -@click.option('-t','--top', type=int, help='Number of keyphrases to extract', default=10, required=False) -@click.option('-v','--verbose', count=True, required=False) - -def keywords(text_input, input_file, language, ngram_size, verbose=False, dedup_func="seqm", dedup_lim=.9, window_size=1, top=10): - def run_yake(text_content): - myake = yake.KeywordExtractor(lan=language, n=ngram_size, dedupLim=dedup_lim, dedupFunc=dedup_func, - windowsSize=window_size, top=top) - results = myake.extract_keywords(text_content) +@click.command() +@click.option( + "-ti", + "--text_input", + help="Input text, SURROUNDED by single quotes(')", + required=False, +) +@click.option( + "-i", + "--input_file", + help="Input file", + required=False, +) +@click.option( + "-l", + "--language", + default="en", + help="Language", + required=False, +) +@click.option( + "-n", + "--ngram_size", + default=3, + help="Max size of the ngram", + type=int, +) +@click.option( + "-df", + "--dedup_func", + help="Deduplication function", + default="seqm", + type=click.Choice(["leve", "jaro", "seqm"]), +) +@click.option( + "-dl", + "--dedup_lim", + help="Deduplication limiar", + default=0.9, + type=float, +) +@click.option( + "-ws", + "--window_size", + help="Window size", + default=1, + type=int, +) +@click.option( + "-t", + "--top", + help="Number of keyphrases to extract", + default=10, + type=int, +) +@click.option( + "-v", + "--verbose", + count=True, + help="Verbose output", +) +@click.pass_context +def keywords( + text_input, + input_file, + language, + ngram_size, + dedup_func, + dedup_lim, + window_size, + top, + verbose, +): + """Extract keywords using YAKE!""" - table = [] - for kw in results: - if (verbose): - table.append({"keyword":kw[0], "score":kw[1]}) - else: - table.append({"keyword":kw[0]}) + def run_yake(text_content): + extractor = yake.KeywordExtractor( + lan=language, + n=ngram_size, + dedupLim=dedup_lim, + dedupFunc=dedup_func, + windowsSize=window_size, + top=top, + ) + results = extractor.extract_keywords(text_content) - print(tabulate(table, headers="keys")) + table = [ + {"keyword": kw[0], "score": kw[1]} if verbose else {"keyword": kw[0]} + for kw in results + ] + print(tabulate(table, headers="keys")) - if text_input and input_file: - print("You should specify either an input file or direct text input, but not both!") - exit(1) - elif not text_input and not input_file: - print("You should specify either an input file or direct text input") - exit(1) - else: - if text_input: - run_yake(text_input) - else: - with open(input_file) as fpath: - text_content = fpath.read() - run_yake(text_content) + if text_input and input_file: + print("Specify either an input file or direct text input, not both!") + sys.exit(1) + elif not text_input and not input_file: + print("Specify either an input file or direct text input") + sys.exit(1) -if __name__ == "__main__": - keywords() + if text_input: + run_yake(text_input) + else: + try: + with open(input_file, encoding="utf-8") as f: + run_yake(f.read()) + except FileNotFoundError: + print(f"File '{input_file}' not found.") + sys.exit(1) diff --git a/yake/core/Levenshtein.py b/yake/core/Levenshtein.py new file mode 100644 index 00000000..c2f82a8f --- /dev/null +++ b/yake/core/Levenshtein.py @@ -0,0 +1,114 @@ +""" +Module providing Levenshtein distance and ratio calculations. + +This module implements the Levenshtein (edit distance) algorithm for measuring +the difference between two strings. It provides both a raw distance calculation +and a normalized similarity ratio, which are useful for comparing text strings +and identifying potential matches with slight variations. +""" + +import numpy as np + + +class Levenshtein: + """ + Class for computing Levenshtein distance and similarity ratio. + + This class provides static methods to calculate the edit distance between + strings (how many insertions, deletions, or substitutions are needed to + transform one string into another) and to determine a normalized similarity + ratio between them. + + These metrics are widely used in fuzzy string matching, spell checking, + and approximate text similarity measurements. + """ + + @staticmethod + def __ratio(distance: float, str_length: int) -> float: + """ + Calculate the similarity ratio based on distance and string length. + + This method normalizes the Levenshtein distance into a similarity ratio + between 0 and 1, where 1 represents identical strings and 0 represents + completely different strings. + + Args: + distance (float): The Levenshtein distance between two strings. + str_length (int): The length of the longer string. + + Returns: + float: The similarity ratio, where higher values indicate greater similarity. + The range is [0.0, 1.0] where 1.0 means identical strings. + """ + return 1 - float(distance) / float(str_length) + + @staticmethod + def ratio(seq1: str, seq2: str) -> float: + """ + Compute the similarity ratio between two strings. + + This is the main method for determining string similarity. It calculates + the Levenshtein distance and then converts it to a ratio representing + how similar the strings are. + + Args: + seq1 (str): The first string to compare. + seq2 (str): The second string to compare. + + Returns: + float: The similarity ratio between the two strings, ranging from 0.0 + (completely different) to 1.0 (identical). + """ + str_distance = Levenshtein.distance(seq1, seq2) + str_length = max(len(seq1), len(seq2)) + return Levenshtein.__ratio(str_distance, str_length) + + @staticmethod + def distance(seq1: str, seq2: str) -> int: + """ + Calculate the Levenshtein distance between two strings. + + This method implements the core Levenshtein algorithm, which calculates + the minimum number of single-character edits (insertions, deletions, or + substitutions) required to change one string into another. + + The algorithm uses dynamic programming with a matrix approach to efficiently + compute the minimum edit distance. + + Args: + seq1 (str): The first string to compare. + seq2 (str): The second string to compare. + + Returns: + int: The Levenshtein distance - the minimum number of edit operations + required to transform seq1 into seq2. + """ + # Create a matrix of size (len(seq1)+1) x (len(seq2)+1) + size_x = len(seq1) + 1 + size_y = len(seq2) + 1 + matrix = np.zeros((size_x, size_y)) + + # Initialize the first row and column of the matrix + for x in range(size_x): + matrix[x, 0] = x # Cost of deleting characters from seq1 + for y in range(size_y): + matrix[0, y] = y # Cost of inserting characters from seq2 + + # Fill the matrix using dynamic programming approach + for x in range(1, size_x): + for y in range(1, size_y): + # Check if the characters at current positions match + if seq1[x - 1] == seq2[y - 1]: + cost = 0 # No cost for matching characters + else: + cost = 1 # Cost of 1 for substitution + + # Calculate minimum cost among deletion, insertion, and substitution + matrix[x, y] = min( + matrix[x - 1, y] + 1, # Deletion (remove from seq1) + matrix[x, y - 1] + 1, # Insertion (add from seq2) + matrix[x - 1, y - 1] + cost, # Substitution or match + ) + + # Return the bottom-right value of the matrix as the final distance + return int(matrix[size_x - 1, size_y - 1]) \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_ar.txt b/yake/core/StopwordsList/stopwords_ar.txt similarity index 88% rename from yake/StopwordsList/stopwords_ar.txt rename to yake/core/StopwordsList/stopwords_ar.txt index 926226ba..da635d77 100644 --- a/yake/StopwordsList/stopwords_ar.txt +++ b/yake/core/StopwordsList/stopwords_ar.txt @@ -1,162 +1,162 @@ -ب -ا -Ø£ -ØŒ -عشر -عدد -عدة -عشرة -عدم -عام -عاما -عن -عند -عندما -على -عليه -عليها -زيارة -سنة -سنوات -تم -ضد -بعد -بعض -اعادة -اعلنت -بسبب -حتى -اذا -احد -اثر -برس -باسم -غدا -شخصا -صباح -اطار -اربعة -اخرى -بان -اجل -غير -بشكل -حاليا -بن -به -ثم -ا٠-ان -او -اي -بها -ØµÙØ± -حيث -اكد -الا -اما -امس -السابق -التى -التي -اكثر -ايار -ايضا -ثلاثة -الذاتي -الاخيرة -الثاني -الثانية -الذى -الذي -الان -امام -ايام -خلال -حوالى -الذين -الاول -الاولى -بين -ذلك -دون -حول -حين -ال٠-الى -انه -اول -ضمن -انها -جميع -الماضي -الوقت -المقبل -اليوم -Ù€ -Ù -Ùˆ -Ùˆ6 -قد -لا -ما -مع -مساء -هذا -واحد -واضا٠-ÙˆØ§Ø¶Ø§ÙØª -ÙØ§Ù† -قبل -قال -كان -لدى -نحو -هذه -وان -واكد -كانت -واوضح -مايو -ÙÙ‰ -ÙÙŠ -كل -لم -لن -له -من -هو -هي -قوة -كما -لها -منذ -وقد -ولا -Ù†ÙØ³Ù‡ -لقاء -مقابل -هناك -وقال -وكان -نهاية -وقالت -وكانت -للامم -Ùيه -كلم -لكن -ÙˆÙÙŠ -وق٠-ولم -ومن -وهو -وهي -يوم -Ùيها -منها -مليار -لوكالة -يكون -يمكن +ب +ا +Ø£ +ØŒ +عشر +عدد +عدة +عشرة +عدم +عام +عاما +عن +عند +عندما +على +عليه +عليها +زيارة +سنة +سنوات +تم +ضد +بعد +بعض +اعادة +اعلنت +بسبب +حتى +اذا +احد +اثر +برس +باسم +غدا +شخصا +صباح +اطار +اربعة +اخرى +بان +اجل +غير +بشكل +حاليا +بن +به +ثم +ا٠+ان +او +اي +بها +ØµÙØ± +حيث +اكد +الا +اما +امس +السابق +التى +التي +اكثر +ايار +ايضا +ثلاثة +الذاتي +الاخيرة +الثاني +الثانية +الذى +الذي +الان +امام +ايام +خلال +حوالى +الذين +الاول +الاولى +بين +ذلك +دون +حول +حين +ال٠+الى +انه +اول +ضمن +انها +جميع +الماضي +الوقت +المقبل +اليوم +Ù€ +Ù +Ùˆ +Ùˆ6 +قد +لا +ما +مع +مساء +هذا +واحد +واضا٠+ÙˆØ§Ø¶Ø§ÙØª +ÙØ§Ù† +قبل +قال +كان +لدى +نحو +هذه +وان +واكد +كانت +واوضح +مايو +ÙÙ‰ +ÙÙŠ +كل +لم +لن +له +من +هو +هي +قوة +كما +لها +منذ +وقد +ولا +Ù†ÙØ³Ù‡ +لقاء +مقابل +هناك +وقال +وكان +نهاية +وقالت +وكانت +للامم +Ùيه +كلم +لكن +ÙˆÙÙŠ +وق٠+ولم +ومن +وهو +وهي +يوم +Ùيها +منها +مليار +لوكالة +يكون +يمكن مليون \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_bg.txt b/yake/core/StopwordsList/stopwords_bg.txt similarity index 90% rename from yake/StopwordsList/stopwords_bg.txt rename to yake/core/StopwordsList/stopwords_bg.txt index 9700c313..7fe42a78 100644 --- a/yake/StopwordsList/stopwords_bg.txt +++ b/yake/core/StopwordsList/stopwords_bg.txt @@ -1,259 +1,259 @@ -а -автентичен -аз -ако -ала -бе -без -беше -би -бивш -бивша -бившо -бил -била -били -било -Ð±Ð»Ð°Ð³Ð¾Ð´Ð°Ñ€Ñ -близо -бъдат -бъде -бÑха -в -Ð²Ð°Ñ -ваш -ваша -вероÑтно -вече -взема -ви -вие -винаги -внимава -време -вÑе -вÑеки -вÑички -вÑичко -вÑÑка -във -въпреки -върху -г -ги -главен -главна -главно -Ð³Ð»Ð°Ñ -го -година -години -годишен -д -да -дали -два -двама -двамата -две -двете -ден -Ð´Ð½ÐµÑ -дни -до -добра -добре -добро -добър -докато -докога -дори -доÑега -доÑта -друг -друга -други -е -евтин -едва -един -една -еднаква -еднакви -еднакъв -едно -екип -ето -живот -за -забавÑм -зад -заедно -заради -заÑега -заÑпал -затова -защо -защото -и -из -или -им -има -имат -иÑка -й -каза -как -каква -какво -както -какъв -като -кога -когато -което -които -кой -който -колко -коÑто -къде -където -към -леÑен -леÑно -ли -лош -м -май -малко -ме -между -мек -мен -меÑец -ми -много -мнозина -мога -могат -може -мокър -Ð¼Ð¾Ð»Ñ -момента -му -н -на -над -назад -най -направи -напред -например -Ð½Ð°Ñ -не -него -нещо -Ð½ÐµÑ -ни -ние -никой -нито -нищо -но -нов -нова -нови -новина -нÑкои -нÑкой -нÑколко -нÑма -обаче -около -оÑвен -оÑобено -от -отгоре -отново -още -пак -по -повече -повечето -под -поне -поради -поÑле -почти -прави -пред -преди -през -при -пък -първата -първи -първо -пъти -равен -равна -Ñ -Ñа -Ñам -Ñамо -Ñе -Ñега -Ñи -Ñин -Ñкоро -Ñлед -Ñледващ -Ñме -ÑмÑÑ… -Ñпоред -Ñред -Ñрещу -Ñте -Ñъм -ÑÑŠÑ -Ñъщо -Ñ‚ -тази -така -такива -такъв -там -твой -те -тези -ти -Ñ‚.н. -то -това -тогава -този -той -толкова -точно -три -трÑбва -тук -тъй -Ñ‚Ñ -Ñ‚ÑÑ… -у -утре -хареÑва -хилÑди -ч -чаÑа -че -чеÑто -чрез -ще -щом -юмрук -Ñ +а +автентичен +аз +ако +ала +бе +без +беше +би +бивш +бивша +бившо +бил +била +били +било +Ð±Ð»Ð°Ð³Ð¾Ð´Ð°Ñ€Ñ +близо +бъдат +бъде +бÑха +в +Ð²Ð°Ñ +ваш +ваша +вероÑтно +вече +взема +ви +вие +винаги +внимава +време +вÑе +вÑеки +вÑички +вÑичко +вÑÑка +във +въпреки +върху +г +ги +главен +главна +главно +Ð³Ð»Ð°Ñ +го +година +години +годишен +д +да +дали +два +двама +двамата +две +двете +ден +Ð´Ð½ÐµÑ +дни +до +добра +добре +добро +добър +докато +докога +дори +доÑега +доÑта +друг +друга +други +е +евтин +едва +един +една +еднаква +еднакви +еднакъв +едно +екип +ето +живот +за +забавÑм +зад +заедно +заради +заÑега +заÑпал +затова +защо +защото +и +из +или +им +има +имат +иÑка +й +каза +как +каква +какво +както +какъв +като +кога +когато +което +които +кой +който +колко +коÑто +къде +където +към +леÑен +леÑно +ли +лош +м +май +малко +ме +между +мек +мен +меÑец +ми +много +мнозина +мога +могат +може +мокър +Ð¼Ð¾Ð»Ñ +момента +му +н +на +над +назад +най +направи +напред +например +Ð½Ð°Ñ +не +него +нещо +Ð½ÐµÑ +ни +ние +никой +нито +нищо +но +нов +нова +нови +новина +нÑкои +нÑкой +нÑколко +нÑма +обаче +около +оÑвен +оÑобено +от +отгоре +отново +още +пак +по +повече +повечето +под +поне +поради +поÑле +почти +прави +пред +преди +през +при +пък +първата +първи +първо +пъти +равен +равна +Ñ +Ñа +Ñам +Ñамо +Ñе +Ñега +Ñи +Ñин +Ñкоро +Ñлед +Ñледващ +Ñме +ÑмÑÑ… +Ñпоред +Ñред +Ñрещу +Ñте +Ñъм +ÑÑŠÑ +Ñъщо +Ñ‚ +тази +така +такива +такъв +там +твой +те +тези +ти +Ñ‚.н. +то +това +тогава +този +той +толкова +точно +три +трÑбва +тук +тъй +Ñ‚Ñ +Ñ‚ÑÑ… +у +утре +хареÑва +хилÑди +ч +чаÑа +че +чеÑто +чрез +ще +щом +юмрук +Ñ Ñк \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_br.txt b/yake/core/StopwordsList/stopwords_br.txt similarity index 85% rename from yake/StopwordsList/stopwords_br.txt rename to yake/core/StopwordsList/stopwords_br.txt index dccacee7..c2884d28 100644 --- a/yake/StopwordsList/stopwords_br.txt +++ b/yake/core/StopwordsList/stopwords_br.txt @@ -1,392 +1,392 @@ -a -à -adeus -agora -aí -ainda -além -algo -algumas -alguns -ali -ano -anos -antes -ao -aos -apenas -apoio -após -aquela -aquelas -aquele -aqueles -aqui -aquilo -área -as -às -assim -até -atrás -através -baixo -bastante -bem -boa -boas -bom -bons -breve -cá -cada -catorze -cedo -cento -certamente -certeza -cima -cinco -coisa -com -como -conselho -contra -custa -da -dá -dão -daquela -daquelas -daquele -daqueles -dar -das -de -debaixo -demais -dentro -depois -desde -dessa -dessas -desse -desses -desta -destas -deste -destes -deve -deverá -dez -dezanove -dezasseis -dezassete -dezoito -dia -diante -diz -dizem -dizer -do -dois -dos -doze -duas -dúvida -e -é -ela -elas -ele -eles -em -embora -entre -era -és -essa -essas -esse -esses -esta -está -estão -estar -estas -estás -estava -este -estes -esteve -estive -estivemos -estiveram -estiveste -estivestes -estou -eu -exemplo -faço -falta -favor -faz -fazeis -fazem -fazemos -fazer -fazes -fez -fim -final -foi -fomos -for -foram -forma -foste -fostes -fui -geral -grande -grandes -grupo -há -hoje -hora -horas -isso -isto -já -lá -lado -local -logo -longe -lugar -maior -maioria -mais -mal -mas -máximo -me -meio -menor -menos -mês -meses -meu -meus -mil -minha -minhas -momento -muito -muitos -na -nada -não -naquela -naquelas -naquele -naqueles -nas -nem -nenhuma -nessa -nessas -nesse -nesses -nesta -nestas -neste -nestes -nível -no -noite -nome -nos -nós -nossa -nossas -nosso -nossos -nova -novas -nove -novo -novos -num -numa -número -nunca -o -obra -obrigada -obrigado -oitava -oitavo -oito -onde -ontem -onze -os -ou -outra -outras -outro -outros -para -parece -parte -partir -paucas -pela -pelas -pelo -pelos -perto -pode -pôde -podem -poder -põe -põem -ponto -pontos -por -porque -porquê -posição -possível -possivelmente -posso -pouca -pouco -poucos -primeira -primeiras -primeiro -primeiros -própria -próprias -próprio -próprios -próxima -próximas -próximo -próximos -puderam -quáis -qual -quando -quanto -quarta -quarto -quatro -que -quê -quem -quer -quereis -querem -queremas -queres -quero -questão -quinta -quinto -quinze -relação -sabe -sabem -são -se -segunda -segundo -sei -seis -sem -sempre -ser -seria -sete -sétima -sétimo -seu -seus -sexta -sexto -sim -sistema -sob -sobre -sois -somos -sou -sua -suas -tal -talvez -também -tanta -tantas -tanto -tão -tarde -te -tem -têm -temos -tendes -tenho -tens -ter -terceira -terceiro -teu -teus -teve -tive -tivemos -tiveram -tiveste -tivestes -toda -todas -todo -todos -trabalho -três -treze -tu -tua -tuas -tudo -um -uma -umas -uns -vai -vais -vão -vários -vem -vêm -vens -ver -vez -vezes -viagem -vindo -vinte -você -vocês -vos -vós -vossa -vossas -vosso -vossos +a +à +adeus +agora +aí +ainda +além +algo +algumas +alguns +ali +ano +anos +antes +ao +aos +apenas +apoio +após +aquela +aquelas +aquele +aqueles +aqui +aquilo +área +as +às +assim +até +atrás +através +baixo +bastante +bem +boa +boas +bom +bons +breve +cá +cada +catorze +cedo +cento +certamente +certeza +cima +cinco +coisa +com +como +conselho +contra +custa +da +dá +dão +daquela +daquelas +daquele +daqueles +dar +das +de +debaixo +demais +dentro +depois +desde +dessa +dessas +desse +desses +desta +destas +deste +destes +deve +deverá +dez +dezanove +dezasseis +dezassete +dezoito +dia +diante +diz +dizem +dizer +do +dois +dos +doze +duas +dúvida +e +é +ela +elas +ele +eles +em +embora +entre +era +és +essa +essas +esse +esses +esta +está +estão +estar +estas +estás +estava +este +estes +esteve +estive +estivemos +estiveram +estiveste +estivestes +estou +eu +exemplo +faço +falta +favor +faz +fazeis +fazem +fazemos +fazer +fazes +fez +fim +final +foi +fomos +for +foram +forma +foste +fostes +fui +geral +grande +grandes +grupo +há +hoje +hora +horas +isso +isto +já +lá +lado +local +logo +longe +lugar +maior +maioria +mais +mal +mas +máximo +me +meio +menor +menos +mês +meses +meu +meus +mil +minha +minhas +momento +muito +muitos +na +nada +não +naquela +naquelas +naquele +naqueles +nas +nem +nenhuma +nessa +nessas +nesse +nesses +nesta +nestas +neste +nestes +nível +no +noite +nome +nos +nós +nossa +nossas +nosso +nossos +nova +novas +nove +novo +novos +num +numa +número +nunca +o +obra +obrigada +obrigado +oitava +oitavo +oito +onde +ontem +onze +os +ou +outra +outras +outro +outros +para +parece +parte +partir +paucas +pela +pelas +pelo +pelos +perto +pode +pôde +podem +poder +põe +põem +ponto +pontos +por +porque +porquê +posição +possível +possivelmente +posso +pouca +pouco +poucos +primeira +primeiras +primeiro +primeiros +própria +próprias +próprio +próprios +próxima +próximas +próximo +próximos +puderam +quáis +qual +quando +quanto +quarta +quarto +quatro +que +quê +quem +quer +quereis +querem +queremas +queres +quero +questão +quinta +quinto +quinze +relação +sabe +sabem +são +se +segunda +segundo +sei +seis +sem +sempre +ser +seria +sete +sétima +sétimo +seu +seus +sexta +sexto +sim +sistema +sob +sobre +sois +somos +sou +sua +suas +tal +talvez +também +tanta +tantas +tanto +tão +tarde +te +tem +têm +temos +tendes +tenho +tens +ter +terceira +terceiro +teu +teus +teve +tive +tivemos +tiveram +tiveste +tivestes +toda +todas +todo +todos +trabalho +três +treze +tu +tua +tuas +tudo +um +uma +umas +uns +vai +vais +vão +vários +vem +vêm +vens +ver +vez +vezes +viagem +vindo +vinte +você +vocês +vos +vós +vossa +vossas +vosso +vossos zero \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_cz.txt b/yake/core/StopwordsList/stopwords_cz.txt similarity index 85% rename from yake/StopwordsList/stopwords_cz.txt rename to yake/core/StopwordsList/stopwords_cz.txt index df359f30..92053012 100644 --- a/yake/StopwordsList/stopwords_cz.txt +++ b/yake/core/StopwordsList/stopwords_cz.txt @@ -1,256 +1,256 @@ -aÄkoli -ahoj -ale -anebo -ano -asi -aspoň -bÄ›hem -bez -beze -blízko -bohužel -brzo -bude -budeme -budeÅ¡ -budete -budou -budu -byl -byla -byli -bylo -byly -bys -Äau -chce -chceme -chceÅ¡ -chcete -chci -chtÄ›jí -chtít -chut' -chuti -co -Ätrnáct -ÄtyÅ™i -dál -dále -daleko -dÄ›kovat -dÄ›kujeme -dÄ›kuji -den -deset -devatenáct -devÄ›t -do -dobrý -docela -dva -dvacet -dvanáct -dvÄ› -hodnÄ› -já -jak -jde -je -jeden -jedenáct -jedna -jedno -jednou -jedou -jeho -její -jejich -jemu -jen -jenom -jeÅ¡tÄ› -jestli -jestliže -jí -jich -jím -jimi -jinak -jsem -jsi -jsme -jsou -jste -kam -kde -kdo -kdy -když -ke -kolik -kromÄ› -která -které -kteří -který -kvůli -má -mají -málo -mám -máme -máš -máte -mé -mÄ› -mezi -mí -mít -mnÄ› -mnou -moc -mohl -mohou -moje -moji -možná -můj -musí -může -my -na -nad -nade -nám -námi -naproti -nás -náš -naÅ¡e -naÅ¡i -ne -nÄ› -nebo -nebyl -nebyla -nebyli -nebyly -nÄ›co -nedÄ›lá -nedÄ›lají -nedÄ›lám -nedÄ›láme -nedÄ›láš -nedÄ›láte -nÄ›jak -nejsi -nÄ›kde -nÄ›kdo -nemají -nemáme -nemáte -nemÄ›l -nÄ›mu -není -nestaÄí -nevadí -než -nic -nich -ním -nimi -nula -od -ode -on -ona -oni -ono -ony -osm -osmnáct -pak -patnáct -pÄ›t -po -pořád -potom -pozdÄ› -pÅ™ed -pÅ™es -pÅ™ese -pro -proÄ -prosím -prostÄ› -proti -protože -rovnÄ› -se -sedm -sedmnáct -Å¡est -Å¡estnáct -skoro -smÄ›jí -smí -snad -spolu -sta -sté -sto -ta -tady -tak -takhle -taky -tam -tamhle -tamhleto -tamto -tÄ› -tebe -tebou -ted' -tedy -ten -ti -tisíc -tisíce -to -tobÄ› -tohle -toto -tÅ™eba -tÅ™i -tÅ™ináct -troÅ¡ku -tvá -tvé -tvoje -tvůj -ty -urÄitÄ› -už -vám -vámi -vás -váš -vaÅ¡e -vaÅ¡i -ve -veÄer -vedle -vlastnÄ› -vÅ¡echno -vÅ¡ichni -vůbec -vy -vždy -za -zaÄ -zatímco -ze +aÄkoli +ahoj +ale +anebo +ano +asi +aspoň +bÄ›hem +bez +beze +blízko +bohužel +brzo +bude +budeme +budeÅ¡ +budete +budou +budu +byl +byla +byli +bylo +byly +bys +Äau +chce +chceme +chceÅ¡ +chcete +chci +chtÄ›jí +chtít +chut' +chuti +co +Ätrnáct +ÄtyÅ™i +dál +dále +daleko +dÄ›kovat +dÄ›kujeme +dÄ›kuji +den +deset +devatenáct +devÄ›t +do +dobrý +docela +dva +dvacet +dvanáct +dvÄ› +hodnÄ› +já +jak +jde +je +jeden +jedenáct +jedna +jedno +jednou +jedou +jeho +její +jejich +jemu +jen +jenom +jeÅ¡tÄ› +jestli +jestliže +jí +jich +jím +jimi +jinak +jsem +jsi +jsme +jsou +jste +kam +kde +kdo +kdy +když +ke +kolik +kromÄ› +která +které +kteří +který +kvůli +má +mají +málo +mám +máme +máš +máte +mé +mÄ› +mezi +mí +mít +mnÄ› +mnou +moc +mohl +mohou +moje +moji +možná +můj +musí +může +my +na +nad +nade +nám +námi +naproti +nás +náš +naÅ¡e +naÅ¡i +ne +nÄ› +nebo +nebyl +nebyla +nebyli +nebyly +nÄ›co +nedÄ›lá +nedÄ›lají +nedÄ›lám +nedÄ›láme +nedÄ›láš +nedÄ›láte +nÄ›jak +nejsi +nÄ›kde +nÄ›kdo +nemají +nemáme +nemáte +nemÄ›l +nÄ›mu +není +nestaÄí +nevadí +než +nic +nich +ním +nimi +nula +od +ode +on +ona +oni +ono +ony +osm +osmnáct +pak +patnáct +pÄ›t +po +pořád +potom +pozdÄ› +pÅ™ed +pÅ™es +pÅ™ese +pro +proÄ +prosím +prostÄ› +proti +protože +rovnÄ› +se +sedm +sedmnáct +Å¡est +Å¡estnáct +skoro +smÄ›jí +smí +snad +spolu +sta +sté +sto +ta +tady +tak +takhle +taky +tam +tamhle +tamhleto +tamto +tÄ› +tebe +tebou +ted' +tedy +ten +ti +tisíc +tisíce +to +tobÄ› +tohle +toto +tÅ™eba +tÅ™i +tÅ™ináct +troÅ¡ku +tvá +tvé +tvoje +tvůj +ty +urÄitÄ› +už +vám +vámi +vás +váš +vaÅ¡e +vaÅ¡i +ve +veÄer +vedle +vlastnÄ› +vÅ¡echno +vÅ¡ichni +vůbec +vy +vždy +za +zaÄ +zatímco +ze že \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_da.txt b/yake/core/StopwordsList/stopwords_da.txt similarity index 83% rename from yake/StopwordsList/stopwords_da.txt rename to yake/core/StopwordsList/stopwords_da.txt index 0dc00731..bffc1a41 100644 --- a/yake/StopwordsList/stopwords_da.txt +++ b/yake/core/StopwordsList/stopwords_da.txt @@ -1,64 +1,64 @@ -De -I -af -aldrig -alle -altid -bagved -de -der -du -efter -eller -en -endnu -et -fjernt -for -foran -fra -fÃ¥ -gennem -god -han -her -hos -hovfor -hun -hurtig -hvad -hvem -hvonÃ¥r -hvor -hvordan -hvorhen -i -imod -ja -jeg -langsom -lidt -mange -med -meget -mellem -mere -mindre -mÃ¥ske -nede -nej -nok -nu -nÃ¥r -og -oppe -pÃ¥ -rask -sammen -temmelig -til -uden -udenfor -under -ved +De +I +af +aldrig +alle +altid +bagved +de +der +du +efter +eller +en +endnu +et +fjernt +for +foran +fra +fÃ¥ +gennem +god +han +her +hos +hovfor +hun +hurtig +hvad +hvem +hvonÃ¥r +hvor +hvordan +hvorhen +i +imod +ja +jeg +langsom +lidt +mange +med +meget +mellem +mere +mindre +mÃ¥ske +nede +nej +nok +nu +nÃ¥r +og +oppe +pÃ¥ +rask +sammen +temmelig +til +uden +udenfor +under +ved vi \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_de.txt b/yake/core/StopwordsList/stopwords_de.txt similarity index 86% rename from yake/StopwordsList/stopwords_de.txt rename to yake/core/StopwordsList/stopwords_de.txt index 094783a5..668fe5e3 100644 --- a/yake/StopwordsList/stopwords_de.txt +++ b/yake/core/StopwordsList/stopwords_de.txt @@ -1,603 +1,603 @@ -a -ab -aber -aber -ach -acht -achte -achten -achter -achtes -ag -alle -allein -allem -allen -aller -allerdings -alles -allgemeinen -als -als -also -am -an -andere -anderen -andern -anders -au -auch -auch -auf -aus -ausser -außer -ausserdem -außerdem -b -bald -bei -beide -beiden -beim -beispiel -bekannt -bereits -besonders -besser -besten -bin -bis -bisher -bist -c -d -da -dabei -dadurch -dafür -dagegen -daher -dahin -dahinter -damals -damit -danach -daneben -dank -dann -daran -darauf -daraus -darf -darfst -darin -darüber -darum -darunter -das -das -dasein -daselbst -dass -daß -dasselbe -davon -davor -dazu -dazwischen -dein -deine -deinem -deiner -dem -dementsprechend -demgegenüber -demgemäss -demgemäß -demselben -demzufolge -den -denen -denn -denn -denselben -der -deren -derjenige -derjenigen -dermassen -dermaßen -derselbe -derselben -des -deshalb -desselben -dessen -deswegen -d.h -dich -die -diejenige -diejenigen -dies -diese -dieselbe -dieselben -diesem -diesen -dieser -dieses -dir -doch -dort -drei -drin -dritte -dritten -dritter -drittes -du -durch -durchaus -dürfen -dürft -durfte -durften -e -eben -ebenso -ehrlich -ei -ei, -ei, -eigen -eigene -eigenen -eigener -eigenes -ein -einander -eine -einem -einen -einer -eines -einige -einigen -einiger -einiges -einmal -einmal -eins -elf -en -ende -endlich -entweder -entweder -er -Ernst -erst -erste -ersten -erster -erstes -es -etwa -etwas -euch -f -früher -fünf -fünfte -fünften -fünfter -fünftes -für -g -gab -ganz -ganze -ganzen -ganzer -ganzes -gar -gedurft -gegen -gegenüber -gehabt -gehen -geht -gekannt -gekonnt -gemacht -gemocht -gemusst -genug -gerade -gern -gesagt -gesagt -geschweige -gewesen -gewollt -geworden -gibt -ging -gleich -gott -gross -groß -grosse -große -grossen -großen -grosser -großer -grosses -großes -gut -gute -guter -gutes -h -habe -haben -habt -hast -hat -hatte -hätte -hatten -hätten -heisst -her -heute -hier -hin -hinter -hoch -i -ich -ihm -ihn -ihnen -ihr -ihre -ihrem -ihren -ihrer -ihres -im -im -immer -in -in -indem -infolgedessen -ins -irgend -ist -j -ja -ja -jahr -jahre -jahren -je -jede -jedem -jeden -jeder -jedermann -jedermanns -jedoch -jemand -jemandem -jemanden -jene -jenem -jenen -jener -jenes -jetzt -k -kam -kann -kannst -kaum -kein -keine -keinem -keinen -keiner -kleine -kleinen -kleiner -kleines -kommen -kommt -können -könnt -konnte -könnte -konnten -kurz -l -lang -lange -lange -leicht -leide -lieber -los -m -machen -macht -machte -mag -magst -mahn -man -manche -manchem -manchen -mancher -manches -mann -mehr -mein -meine -meinem -meinen -meiner -meines -mensch -menschen -mich -mir -mit -mittel -mochte -möchte -mochten -mögen -möglich -mögt -morgen -muss -muß -müssen -musst -müsst -musste -mussten -n -na -nach -nachdem -nahm -natürlich -neben -nein -neue -neuen -neun -neunte -neunten -neunter -neuntes -nicht -nicht -nichts -nie -niemand -niemandem -niemanden -noch -nun -nun -nur -o -ob -ob -oben -oder -oder -offen -oft -oft -ohne -Ordnung -p -q -r -recht -rechte -rechten -rechter -rechtes -richtig -rund -s -sa -sache -sagt -sagte -sah -satt -schlecht -Schluss -schon -sechs -sechste -sechsten -sechster -sechstes -sehr -sei -sei -seid -seien -sein -seine -seinem -seinen -seiner -seines -seit -seitdem -selbst -selbst -sich -sie -sieben -siebente -siebenten -siebenter -siebentes -sind -so -solang -solche -solchem -solchen -solcher -solches -soll -sollen -sollte -sollten -sondern -sonst -sowie -später -statt -t -tag -tage -tagen -tat -teil -tel -tritt -trotzdem -tun -u -über -überhaupt -übrigens -uhr -um -und -und? -uns -unser -unsere -unserer -unter -v -vergangenen -viel -viele -vielem -vielen -vielleicht -vier -vierte -vierten -vierter -viertes -vom -von -vor -w -wahr? -während -währenddem -währenddessen -wann -war -wäre -waren -wart -warum -was -wegen -weil -weit -weiter -weitere -weiteren -weiteres -welche -welchem -welchen -welcher -welches -wem -wen -wenig -wenig -wenige -weniger -weniges -wenigstens -wenn -wenn -wer -werde -werden -werdet -wessen -wie -wie -wieder -will -willst -wir -wird -wirklich -wirst -wo -wohl -wollen -wollt -wollte -wollten -worden -wurde -würde -wurden -würden -x -y -z -z.b -zehn -zehnte -zehnten -zehnter -zehntes -zeit -zu -zuerst -zugleich -zum -zum -zunächst -zur -zurück -zusammen -zwanzig -zwar -zwar -zwei -zweite -zweiten -zweiter -zweites -zwischen -zwölf +a +ab +aber +aber +ach +acht +achte +achten +achter +achtes +ag +alle +allein +allem +allen +aller +allerdings +alles +allgemeinen +als +als +also +am +an +andere +anderen +andern +anders +au +auch +auch +auf +aus +ausser +außer +ausserdem +außerdem +b +bald +bei +beide +beiden +beim +beispiel +bekannt +bereits +besonders +besser +besten +bin +bis +bisher +bist +c +d +da +dabei +dadurch +dafür +dagegen +daher +dahin +dahinter +damals +damit +danach +daneben +dank +dann +daran +darauf +daraus +darf +darfst +darin +darüber +darum +darunter +das +das +dasein +daselbst +dass +daß +dasselbe +davon +davor +dazu +dazwischen +dein +deine +deinem +deiner +dem +dementsprechend +demgegenüber +demgemäss +demgemäß +demselben +demzufolge +den +denen +denn +denn +denselben +der +deren +derjenige +derjenigen +dermassen +dermaßen +derselbe +derselben +des +deshalb +desselben +dessen +deswegen +d.h +dich +die +diejenige +diejenigen +dies +diese +dieselbe +dieselben +diesem +diesen +dieser +dieses +dir +doch +dort +drei +drin +dritte +dritten +dritter +drittes +du +durch +durchaus +dürfen +dürft +durfte +durften +e +eben +ebenso +ehrlich +ei +ei, +ei, +eigen +eigene +eigenen +eigener +eigenes +ein +einander +eine +einem +einen +einer +eines +einige +einigen +einiger +einiges +einmal +einmal +eins +elf +en +ende +endlich +entweder +entweder +er +Ernst +erst +erste +ersten +erster +erstes +es +etwa +etwas +euch +f +früher +fünf +fünfte +fünften +fünfter +fünftes +für +g +gab +ganz +ganze +ganzen +ganzer +ganzes +gar +gedurft +gegen +gegenüber +gehabt +gehen +geht +gekannt +gekonnt +gemacht +gemocht +gemusst +genug +gerade +gern +gesagt +gesagt +geschweige +gewesen +gewollt +geworden +gibt +ging +gleich +gott +gross +groß +grosse +große +grossen +großen +grosser +großer +grosses +großes +gut +gute +guter +gutes +h +habe +haben +habt +hast +hat +hatte +hätte +hatten +hätten +heisst +her +heute +hier +hin +hinter +hoch +i +ich +ihm +ihn +ihnen +ihr +ihre +ihrem +ihren +ihrer +ihres +im +im +immer +in +in +indem +infolgedessen +ins +irgend +ist +j +ja +ja +jahr +jahre +jahren +je +jede +jedem +jeden +jeder +jedermann +jedermanns +jedoch +jemand +jemandem +jemanden +jene +jenem +jenen +jener +jenes +jetzt +k +kam +kann +kannst +kaum +kein +keine +keinem +keinen +keiner +kleine +kleinen +kleiner +kleines +kommen +kommt +können +könnt +konnte +könnte +konnten +kurz +l +lang +lange +lange +leicht +leide +lieber +los +m +machen +macht +machte +mag +magst +mahn +man +manche +manchem +manchen +mancher +manches +mann +mehr +mein +meine +meinem +meinen +meiner +meines +mensch +menschen +mich +mir +mit +mittel +mochte +möchte +mochten +mögen +möglich +mögt +morgen +muss +muß +müssen +musst +müsst +musste +mussten +n +na +nach +nachdem +nahm +natürlich +neben +nein +neue +neuen +neun +neunte +neunten +neunter +neuntes +nicht +nicht +nichts +nie +niemand +niemandem +niemanden +noch +nun +nun +nur +o +ob +ob +oben +oder +oder +offen +oft +oft +ohne +Ordnung +p +q +r +recht +rechte +rechten +rechter +rechtes +richtig +rund +s +sa +sache +sagt +sagte +sah +satt +schlecht +Schluss +schon +sechs +sechste +sechsten +sechster +sechstes +sehr +sei +sei +seid +seien +sein +seine +seinem +seinen +seiner +seines +seit +seitdem +selbst +selbst +sich +sie +sieben +siebente +siebenten +siebenter +siebentes +sind +so +solang +solche +solchem +solchen +solcher +solches +soll +sollen +sollte +sollten +sondern +sonst +sowie +später +statt +t +tag +tage +tagen +tat +teil +tel +tritt +trotzdem +tun +u +über +überhaupt +übrigens +uhr +um +und +und? +uns +unser +unsere +unserer +unter +v +vergangenen +viel +viele +vielem +vielen +vielleicht +vier +vierte +vierten +vierter +viertes +vom +von +vor +w +wahr? +während +währenddem +währenddessen +wann +war +wäre +waren +wart +warum +was +wegen +weil +weit +weiter +weitere +weiteren +weiteres +welche +welchem +welchen +welcher +welches +wem +wen +wenig +wenig +wenige +weniger +weniges +wenigstens +wenn +wenn +wer +werde +werden +werdet +wessen +wie +wie +wieder +will +willst +wir +wird +wirklich +wirst +wo +wohl +wollen +wollt +wollte +wollten +worden +wurde +würde +wurden +würden +x +y +z +z.b +zehn +zehnte +zehnten +zehnter +zehntes +zeit +zu +zuerst +zugleich +zum +zum +zunächst +zur +zurück +zusammen +zwanzig +zwar +zwar +zwei +zweite +zweiten +zweiter +zweites +zwischen +zwölf diff --git a/yake/StopwordsList/stopwords_el.txt b/yake/core/StopwordsList/stopwords_el.txt similarity index 91% rename from yake/StopwordsList/stopwords_el.txt rename to yake/core/StopwordsList/stopwords_el.txt index 15b21f28..dc17b6c1 100644 --- a/yake/StopwordsList/stopwords_el.txt +++ b/yake/core/StopwordsList/stopwords_el.txt @@ -1,844 +1,844 @@ -ένα -έναν -ένας -αδιακοπα -αι -ακομα -ακομη -ακÏιβως -αληθεια -αληθινα -αλλα -αλλαχου -αλλες -αλλη -αλλην -αλλης -αλλιως -αλλιωτικα -αλλο -αλλοι -αλλοιως -αλλοιωτικα -αλλον -αλλος -αλλοτε -αλλου -αλλους -αλλων -αμα -αμεσα -αμεσως -αν -ανα -αναμεσα -αναμεταξυ -ανευ -αντι -αντιπεÏα -αντις -ανω -ανωτεÏω -αξαφνα -απ -απεναντι -απο -αποψε -από -αÏα -αÏαγε -αÏγα -αÏγοτεÏο -αÏιστεÏα -αÏκετα -αÏχικα -ας -αυÏιο -αυτα -αυτες -αυτεσ -αυτη -αυτην -αυτης -αυτο -αυτοι -αυτον -αυτος -αυτοσ -αυτου -αυτους -αυτουσ -αυτων -αφοτου -αφου -αἱ -αἳ -αἵ -αá½Ï„όσ -αá½Ï„ὸς -αὖ -βεβαια -βεβαιοτατα -Î³Î¬Ï -γα -γα^ -γε -γι -για -γοῦν -γÏηγοÏα -γυÏω -Î³á½°Ï -δ' -δέ -δή -δα -δαί -δαίσ -δαὶ -δαὶς -δε -δε -δεινα -δεν -δεν -δεξια -δηθεν -δηλαδη -δι -δι -δι' -διά -δια -δια -διαÏκως -δικα -δικο -δικοι -δικος -δικου -δικους -διολου -διπλα -διχως -διὰ -δὲ -δὴ -δ’ -εαν -εαυτο -εαυτον -εαυτου -εαυτους -εαυτων -εγκαιÏα -εγκαιÏως -εγω -εδω -ειδεμη -ειθε -ειμαι -ειμαστε -ειναι -εις -εισαι -εισαστε -ειστε -ειτε -ειχα -ειχαμε -ειχαν -ειχατε -ειχε -ειχες -εκ -εκαστα -εκαστες -εκαστη -εκαστην -εκαστης -εκαστο -εκαστοι -εκαστον -εκαστος -εκαστου -εκαστους -εκαστων -εκει -εκεινα -εκεινες -εκεινεσ -εκεινη -εκεινην -εκεινης -εκεινο -εκεινοι -εκεινον -εκεινος -εκεινοσ -εκεινου -εκεινους -εκεινουσ -εκεινων -εκτος -εμας -εμεις -εμενα -εμπÏος -εν -ενα -εναν -ενας -ενος -εντελως -εντος -εντωμεταξυ -ενω -ενός -εξ -εξαφνα -εξης -εξισου -εξω -επ -επί -επανω -επειδη -επειτα -επι -επισης -επομενως -εσας -εσεις -εσενα -εστω -εσυ -ετεÏα -ετεÏαι -ετεÏας -ετεÏες -ετεÏη -ετεÏης -ετεÏο -ετεÏοι -ετεÏον -ετεÏος -ετεÏου -ετεÏους -ετεÏων -ετουτα -ετουτες -ετουτη -ετουτην -ετουτης -ετουτο -ετουτοι -ετουτον -ετουτος -ετουτου -ετουτους -ετουτων -ετσι -ευγε -ευθυς -ευτυχως -εφεξης -εχει -εχεις -εχετε -εχθες -εχομε -εχουμε -εχουν -εχτες -εχω -εως -εἰ -εἰμί -εἰμὶ -εἰς -εἰσ -εἴ -εἴμι -εἴτε -η -ηδη -ημασταν -ημαστε -ημουν -ησασταν -ησαστε -ησουν -ηταν -ητανε -ητοι -ηττον -θα -ιδια -ιδιαν -ιδιας -ιδιες -ιδιο -ιδιοι -ιδιον -ιδιος -ιδιου -ιδιους -ιδιων -ιδιως -ισαμε -ισια -ισως -ισωσ -κ -καί -καίτοι -καθ -καθε -καθεμια -καθεμιας -καθενα -καθενας -καθενος -καθετι -καθολου -καθως -και -κακα -κακως -καλα -καλως -καμια -καμιαν -καμιας -καμποσα -καμποσες -καμποση -καμποσην -καμποσης -καμποσο -καμποσοι -καμποσον -καμποσος -καμποσου -καμποσους -καμποσων -κανεις -κανεν -κανενα -κανεναν -κανενας -κανενος -καποια -καποιαν -καποιας -καποιες -καποιο -καποιοι -καποιον -καποιος -καποιου -καποιους -καποιων -καποτε -καπου -καπως -κατ -κατά -κατα -κατι -κατιτι -κατοπιν -κατω -κατὰ -καὶ -κι -κιολας -κλπ -κοντα -κτλ -κυÏιως -κἀν -κἂν -λιγακι -λιγο -λιγωτεÏο -λογω -λοιπα -λοιπον -μέν -μέσα -μή -μήτε -μία -μα -μαζι -μακαÏι -μακÏυα -μαλιστα -μαλλον -μας -με -μεθ -μεθαυÏιο -μειον -μελει -μελλεται -μεμιας -μεν -μεÏικα -μεÏικες -μεÏικοι -μεÏικους -μεÏικων -μεσα -μετ -μετά -μετα -μεταξυ -μετὰ -μεχÏι -μη -μηδε -μην -μηπως -μητε -μιά -μια -μιαν -μιας -μολις -μολονοτι -μοναχα -μονες -μονη -μονην -μονης -μονο -μονοι -μονομιας -μονος -μονου -μονους -μονων -μου -μποÏει -μποÏουν -μπÏαβο -μπÏος -μá¼Î½ -μὲν -μὴ -μὴν -να -ναι -νωÏις -ξανα -ξαφνικα -ο -οι -ολα -ολες -ολη -ολην -ολης -ολο -ολογυÏα -ολοι -ολον -ολονεν -ολος -ολοτελα -ολου -ολους -ολων -ολως -ολωςδιολου -ομως -ομωσ -οποια -οποιαδηποτε -οποιαν -οποιανδηποτε -οποιας -οποιαςδηποτε -οποιδηποτε -οποιες -οποιεσδηποτε -οποιο -οποιοδηποτε -οποιοι -οποιον -οποιονδηποτε -οποιος -οποιοσδηποτε -οποιου -οποιουδηποτε -οποιους -οποιουσδηποτε -οποιων -οποιωνδηποτε -οποτε -οποτεδηποτε -οπου -οπουδηποτε -οπως -οπωσ -οÏισμενα -οÏισμενες -οÏισμενων -οÏισμενως -οσα -οσαδηποτε -οσες -οσεςδηποτε -οση -οσηδηποτε -οσην -οσηνδηποτε -οσης -οσο -οσοδηποτε -οσοι -οσοιδηποτε -οσον -οσονδηποτε -οσος -οσοσδηποτε -οσου -οσουδηποτε -οσους -οσουσδηποτε -οσων -οσωνδηποτε -οταν -οτι -οτιδηποτε -οτου -ου -ουδε -ουτε -οχι -οἱ -οἳ -οἷς -οὠ-οá½Î´ -οá½Î´Î­ -οá½Î´ÎµÎ¯Ïƒ -οá½Î´Îµá½¶Ï‚ -οá½Î´á½² -οá½Î´á½²Î½ -οá½Îº -οá½Ï‡ -οá½Ï‡á½¶ -οὓς -οὔτε -οὕτω -οὕτως -οὕτωσ -οὖν -οὗ -οὗτος -οὗτοσ -παλι -παντοτε -παντου -παντως -Ï€Î±Ï -παÏά -παÏα -παÏá½° -πεÏί -πεÏα -πεÏι -πεÏιπου -πεÏισσοτεÏο -πεÏσι -πεÏυσι -πεÏá½¶ -πια -πιθανον -πιο -πισω -πλαι -πλεον -πλην -ποια -ποιαν -ποιας -ποιες -ποιεσ -ποιο -ποιοι -ποιον -ποιος -ποιοσ -ποιου -ποιους -ποιουσ -ποιων -πολυ -ποσες -ποση -ποσην -ποσης -ποσοι -ποσος -ποσους -ποτε -που -πουθε -πουθενα -ποῦ -Ï€Ïεπει -Ï€Ïιν -Ï€Ïο -Ï€Ïοκειμενου -Ï€Ïοκειται -Ï€ÏοπεÏσι -Ï€Ïος -Ï€Ïοσ -Ï€Ïοτου -Ï€Ïοχθες -Ï€Ïοχτες -Ï€ÏωτυτεÏα -Ï€Ïόσ -Ï€Ïὸ -Ï€Ïὸς -πως -πωσ -σαν -σας -σε -σεις -σημεÏα -σιγα -σου -στα -στη -στην -στης -στις -στο -στον -στου -στους -στων -συγχÏονως -συν -συναμα -συνεπως -συνηθως -συχνα -συχνας -συχνες -συχνη -συχνην -συχνης -συχνο -συχνοι -συχνον -συχνος -συχνου -συχνους -συχνων -συχνως -σχεδον -σωστα -σόσ -ÏƒÏ -σÏν -σὸς -σὺ -σὺν -τά -τήν -τί -τίς -τίσ -τα -ταδε -ταυτα -ταυτες -ταυτη -ταυτην -ταυτης -ταυτο -ταυτον -ταυτος -ταυτου -ταυτων -ταχα -ταχατε -ταῖς -τε -τελικα -τελικως -τες -τετοια -τετοιαν -τετοιας -τετοιες -τετοιο -τετοιοι -τετοιον -τετοιος -τετοιου -τετοιους -τετοιων -τη -την -της -τησ -τι -τινα -τιποτα -τιποτε -τις -τισ -το -τοί -τοι -τοιοῦτος -τοιοῦτοσ -τον -τος -τοσα -τοσες -τοση -τοσην -τοσης -τοσο -τοσοι -τοσον -τοσος -τοσου -τοσους -τοσων -τοτε -του -τουλαχιστο -τουλαχιστον -τους -τουτα -τουτες -τουτη -τουτην -τουτης -τουτο -τουτοι -τουτοις -τουτον -τουτος -τουτου -τουτους -τουτων -τοÏσ -τοὺς -τοῖς -τοῦ -τυχον -των -τωÏα -τό -τόν -τότε -τὰ -τὰς -τὴν -τὸ -τὸν -τῆς -τῆσ -τῇ -τῶν -τῷ -Ï…Ï€ -Ï…Ï€ÎµÏ -υπο -υποψη -υποψιν -υπό -υστεÏα -φετος -χαμηλα -χθες -χτες -χωÏις -χωÏιστα -ψηλα -ω -ωÏαια -ως -ωσ -ωσαν -ωσοτου -ωσπου -ωστε -ωστοσο -ωχ -ἀλλ' -ἀλλά -ἀλλὰ -ἀλλ’ -ἀπ -ἀπό -ἀπὸ -ἀφ -ἂν -ἃ -ἄλλος -ἄλλοσ -ἄν -ἄÏα -ἅμα -á¼Î¬Î½ -á¼Î³ÏŽ -á¼Î³á½¼ -á¼Îº -á¼Î¼ÏŒÏƒ -á¼Î¼á½¸Ï‚ -á¼Î½ -á¼Î¾ -á¼Ï€Î¯ -á¼Ï€Îµá½¶ -á¼Ï€á½¶ -á¼ÏƒÏ„ι -á¼Ï† -á¼á½°Î½ -ἑαυτοῦ -ἔτι -ἡ -á¼¢ -á¼£ -ἤ -á¼¥ -á¼§Ï‚ -ἵνα -á½ -ὃ -ὃν -ὃς -á½… -ὅδε -ὅθεν -á½…Ï€ÎµÏ -á½…Ï‚ -ὅσ -ὅστις -ὅστισ -ὅτε -ὅτι -ὑμόσ -ὑπ -á½‘Ï€Î­Ï -ὑπό -á½‘Ï€á½²Ï -ὑπὸ -ὡς -ὡσ -ὥς -ὥστε -ὦ +ένα +έναν +ένας +αδιακοπα +αι +ακομα +ακομη +ακÏιβως +αληθεια +αληθινα +αλλα +αλλαχου +αλλες +αλλη +αλλην +αλλης +αλλιως +αλλιωτικα +αλλο +αλλοι +αλλοιως +αλλοιωτικα +αλλον +αλλος +αλλοτε +αλλου +αλλους +αλλων +αμα +αμεσα +αμεσως +αν +ανα +αναμεσα +αναμεταξυ +ανευ +αντι +αντιπεÏα +αντις +ανω +ανωτεÏω +αξαφνα +απ +απεναντι +απο +αποψε +από +αÏα +αÏαγε +αÏγα +αÏγοτεÏο +αÏιστεÏα +αÏκετα +αÏχικα +ας +αυÏιο +αυτα +αυτες +αυτεσ +αυτη +αυτην +αυτης +αυτο +αυτοι +αυτον +αυτος +αυτοσ +αυτου +αυτους +αυτουσ +αυτων +αφοτου +αφου +αἱ +αἳ +αἵ +αá½Ï„όσ +αá½Ï„ὸς +αὖ +βεβαια +βεβαιοτατα +Î³Î¬Ï +γα +γα^ +γε +γι +για +γοῦν +γÏηγοÏα +γυÏω +Î³á½°Ï +δ' +δέ +δή +δα +δαί +δαίσ +δαὶ +δαὶς +δε +δε +δεινα +δεν +δεν +δεξια +δηθεν +δηλαδη +δι +δι +δι' +διά +δια +δια +διαÏκως +δικα +δικο +δικοι +δικος +δικου +δικους +διολου +διπλα +διχως +διὰ +δὲ +δὴ +δ’ +εαν +εαυτο +εαυτον +εαυτου +εαυτους +εαυτων +εγκαιÏα +εγκαιÏως +εγω +εδω +ειδεμη +ειθε +ειμαι +ειμαστε +ειναι +εις +εισαι +εισαστε +ειστε +ειτε +ειχα +ειχαμε +ειχαν +ειχατε +ειχε +ειχες +εκ +εκαστα +εκαστες +εκαστη +εκαστην +εκαστης +εκαστο +εκαστοι +εκαστον +εκαστος +εκαστου +εκαστους +εκαστων +εκει +εκεινα +εκεινες +εκεινεσ +εκεινη +εκεινην +εκεινης +εκεινο +εκεινοι +εκεινον +εκεινος +εκεινοσ +εκεινου +εκεινους +εκεινουσ +εκεινων +εκτος +εμας +εμεις +εμενα +εμπÏος +εν +ενα +εναν +ενας +ενος +εντελως +εντος +εντωμεταξυ +ενω +ενός +εξ +εξαφνα +εξης +εξισου +εξω +επ +επί +επανω +επειδη +επειτα +επι +επισης +επομενως +εσας +εσεις +εσενα +εστω +εσυ +ετεÏα +ετεÏαι +ετεÏας +ετεÏες +ετεÏη +ετεÏης +ετεÏο +ετεÏοι +ετεÏον +ετεÏος +ετεÏου +ετεÏους +ετεÏων +ετουτα +ετουτες +ετουτη +ετουτην +ετουτης +ετουτο +ετουτοι +ετουτον +ετουτος +ετουτου +ετουτους +ετουτων +ετσι +ευγε +ευθυς +ευτυχως +εφεξης +εχει +εχεις +εχετε +εχθες +εχομε +εχουμε +εχουν +εχτες +εχω +εως +εἰ +εἰμί +εἰμὶ +εἰς +εἰσ +εἴ +εἴμι +εἴτε +η +ηδη +ημασταν +ημαστε +ημουν +ησασταν +ησαστε +ησουν +ηταν +ητανε +ητοι +ηττον +θα +ιδια +ιδιαν +ιδιας +ιδιες +ιδιο +ιδιοι +ιδιον +ιδιος +ιδιου +ιδιους +ιδιων +ιδιως +ισαμε +ισια +ισως +ισωσ +κ +καί +καίτοι +καθ +καθε +καθεμια +καθεμιας +καθενα +καθενας +καθενος +καθετι +καθολου +καθως +και +κακα +κακως +καλα +καλως +καμια +καμιαν +καμιας +καμποσα +καμποσες +καμποση +καμποσην +καμποσης +καμποσο +καμποσοι +καμποσον +καμποσος +καμποσου +καμποσους +καμποσων +κανεις +κανεν +κανενα +κανεναν +κανενας +κανενος +καποια +καποιαν +καποιας +καποιες +καποιο +καποιοι +καποιον +καποιος +καποιου +καποιους +καποιων +καποτε +καπου +καπως +κατ +κατά +κατα +κατι +κατιτι +κατοπιν +κατω +κατὰ +καὶ +κι +κιολας +κλπ +κοντα +κτλ +κυÏιως +κἀν +κἂν +λιγακι +λιγο +λιγωτεÏο +λογω +λοιπα +λοιπον +μέν +μέσα +μή +μήτε +μία +μα +μαζι +μακαÏι +μακÏυα +μαλιστα +μαλλον +μας +με +μεθ +μεθαυÏιο +μειον +μελει +μελλεται +μεμιας +μεν +μεÏικα +μεÏικες +μεÏικοι +μεÏικους +μεÏικων +μεσα +μετ +μετά +μετα +μεταξυ +μετὰ +μεχÏι +μη +μηδε +μην +μηπως +μητε +μιά +μια +μιαν +μιας +μολις +μολονοτι +μοναχα +μονες +μονη +μονην +μονης +μονο +μονοι +μονομιας +μονος +μονου +μονους +μονων +μου +μποÏει +μποÏουν +μπÏαβο +μπÏος +μá¼Î½ +μὲν +μὴ +μὴν +να +ναι +νωÏις +ξανα +ξαφνικα +ο +οι +ολα +ολες +ολη +ολην +ολης +ολο +ολογυÏα +ολοι +ολον +ολονεν +ολος +ολοτελα +ολου +ολους +ολων +ολως +ολωςδιολου +ομως +ομωσ +οποια +οποιαδηποτε +οποιαν +οποιανδηποτε +οποιας +οποιαςδηποτε +οποιδηποτε +οποιες +οποιεσδηποτε +οποιο +οποιοδηποτε +οποιοι +οποιον +οποιονδηποτε +οποιος +οποιοσδηποτε +οποιου +οποιουδηποτε +οποιους +οποιουσδηποτε +οποιων +οποιωνδηποτε +οποτε +οποτεδηποτε +οπου +οπουδηποτε +οπως +οπωσ +οÏισμενα +οÏισμενες +οÏισμενων +οÏισμενως +οσα +οσαδηποτε +οσες +οσεςδηποτε +οση +οσηδηποτε +οσην +οσηνδηποτε +οσης +οσο +οσοδηποτε +οσοι +οσοιδηποτε +οσον +οσονδηποτε +οσος +οσοσδηποτε +οσου +οσουδηποτε +οσους +οσουσδηποτε +οσων +οσωνδηποτε +οταν +οτι +οτιδηποτε +οτου +ου +ουδε +ουτε +οχι +οἱ +οἳ +οἷς +οὠ+οá½Î´ +οá½Î´Î­ +οá½Î´ÎµÎ¯Ïƒ +οá½Î´Îµá½¶Ï‚ +οá½Î´á½² +οá½Î´á½²Î½ +οá½Îº +οá½Ï‡ +οá½Ï‡á½¶ +οὓς +οὔτε +οὕτω +οὕτως +οὕτωσ +οὖν +οὗ +οὗτος +οὗτοσ +παλι +παντοτε +παντου +παντως +Ï€Î±Ï +παÏά +παÏα +παÏá½° +πεÏί +πεÏα +πεÏι +πεÏιπου +πεÏισσοτεÏο +πεÏσι +πεÏυσι +πεÏá½¶ +πια +πιθανον +πιο +πισω +πλαι +πλεον +πλην +ποια +ποιαν +ποιας +ποιες +ποιεσ +ποιο +ποιοι +ποιον +ποιος +ποιοσ +ποιου +ποιους +ποιουσ +ποιων +πολυ +ποσες +ποση +ποσην +ποσης +ποσοι +ποσος +ποσους +ποτε +που +πουθε +πουθενα +ποῦ +Ï€Ïεπει +Ï€Ïιν +Ï€Ïο +Ï€Ïοκειμενου +Ï€Ïοκειται +Ï€ÏοπεÏσι +Ï€Ïος +Ï€Ïοσ +Ï€Ïοτου +Ï€Ïοχθες +Ï€Ïοχτες +Ï€ÏωτυτεÏα +Ï€Ïόσ +Ï€Ïὸ +Ï€Ïὸς +πως +πωσ +σαν +σας +σε +σεις +σημεÏα +σιγα +σου +στα +στη +στην +στης +στις +στο +στον +στου +στους +στων +συγχÏονως +συν +συναμα +συνεπως +συνηθως +συχνα +συχνας +συχνες +συχνη +συχνην +συχνης +συχνο +συχνοι +συχνον +συχνος +συχνου +συχνους +συχνων +συχνως +σχεδον +σωστα +σόσ +ÏƒÏ +σÏν +σὸς +σὺ +σὺν +τά +τήν +τί +τίς +τίσ +τα +ταδε +ταυτα +ταυτες +ταυτη +ταυτην +ταυτης +ταυτο +ταυτον +ταυτος +ταυτου +ταυτων +ταχα +ταχατε +ταῖς +τε +τελικα +τελικως +τες +τετοια +τετοιαν +τετοιας +τετοιες +τετοιο +τετοιοι +τετοιον +τετοιος +τετοιου +τετοιους +τετοιων +τη +την +της +τησ +τι +τινα +τιποτα +τιποτε +τις +τισ +το +τοί +τοι +τοιοῦτος +τοιοῦτοσ +τον +τος +τοσα +τοσες +τοση +τοσην +τοσης +τοσο +τοσοι +τοσον +τοσος +τοσου +τοσους +τοσων +τοτε +του +τουλαχιστο +τουλαχιστον +τους +τουτα +τουτες +τουτη +τουτην +τουτης +τουτο +τουτοι +τουτοις +τουτον +τουτος +τουτου +τουτους +τουτων +τοÏσ +τοὺς +τοῖς +τοῦ +τυχον +των +τωÏα +τό +τόν +τότε +τὰ +τὰς +τὴν +τὸ +τὸν +τῆς +τῆσ +τῇ +τῶν +τῷ +Ï…Ï€ +Ï…Ï€ÎµÏ +υπο +υποψη +υποψιν +υπό +υστεÏα +φετος +χαμηλα +χθες +χτες +χωÏις +χωÏιστα +ψηλα +ω +ωÏαια +ως +ωσ +ωσαν +ωσοτου +ωσπου +ωστε +ωστοσο +ωχ +ἀλλ' +ἀλλά +ἀλλὰ +ἀλλ’ +ἀπ +ἀπό +ἀπὸ +ἀφ +ἂν +ἃ +ἄλλος +ἄλλοσ +ἄν +ἄÏα +ἅμα +á¼Î¬Î½ +á¼Î³ÏŽ +á¼Î³á½¼ +á¼Îº +á¼Î¼ÏŒÏƒ +á¼Î¼á½¸Ï‚ +á¼Î½ +á¼Î¾ +á¼Ï€Î¯ +á¼Ï€Îµá½¶ +á¼Ï€á½¶ +á¼ÏƒÏ„ι +á¼Ï† +á¼á½°Î½ +ἑαυτοῦ +ἔτι +ἡ +á¼¢ +á¼£ +ἤ +á¼¥ +á¼§Ï‚ +ἵνα +á½ +ὃ +ὃν +ὃς +á½… +ὅδε +ὅθεν +á½…Ï€ÎµÏ +á½…Ï‚ +ὅσ +ὅστις +ὅστισ +ὅτε +ὅτι +ὑμόσ +ὑπ +á½‘Ï€Î­Ï +ὑπό +á½‘Ï€á½²Ï +ὑπὸ +ὡς +ὡσ +ὥς +ὥστε +ὦ á¾§ \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_en.txt b/yake/core/StopwordsList/stopwords_en.txt similarity index 86% rename from yake/StopwordsList/stopwords_en.txt rename to yake/core/StopwordsList/stopwords_en.txt index fd50d8a5..5d5bbc05 100644 --- a/yake/StopwordsList/stopwords_en.txt +++ b/yake/core/StopwordsList/stopwords_en.txt @@ -1,575 +1,575 @@ -dr -dra -mr -ms -a -a's -able -about -above -according -accordingly -across -actually -after -afterwards -again -against -ain't -all -allow -allows -almost -alone -along -already -also -although -always -am -among -amongst -an -and -another -any -anybody -anyhow -anyone -anything -anyway -anyways -anywhere -apart -appear -appreciate -appropriate -are -aren't -around -as -aside -ask -asking -associated -at -available -away -awfully -b -be -became -because -become -becomes -becoming -been -before -beforehand -behind -being -believe -below -beside -besides -best -better -between -beyond -both -brief -but -by -c -c'mon -c's -came -can -can't -cannot -cant -cause -causes -certain -certainly -changes -clearly -co -com -come -comes -concerning -consequently -consider -considering -contain -containing -contains -corresponding -could -couldn't -course -currently -d -definitely -described -despite -did -didn't -different -do -does -doesn't -doing -don't -done -down -downwards -during -e -each -edu -eg -eight -either -else -elsewhere -enough -entirely -especially -et -etc -even -ever -every -everybody -everyone -everything -everywhere -ex -exactly -example -except -f -far -few -fifth -first -five -followed -following -follows -for -former -formerly -forth -four -from -further -furthermore -g -get -gets -getting -given -gives -go -goes -going -gone -got -gotten -greetings -h -had -hadn't -happens -hardly -has -hasn't -have -haven't -having -he -he's -hello -help -hence -her -here -here's -hereafter -hereby -herein -hereupon -hers -herself -hi -him -himself -his -hither -hopefully -how -howbeit -however -i -i'd -i'll -i'm -i've -ie -if -ignored -immediate -in -inasmuch -inc -indeed -indicate -indicated -indicates -inner -insofar -instead -into -inward -is -isn't -it -it'd -it'll -it's -its -itself -j -just -k -keep -keeps -kept -know -knows -known -l -last -lately -later -latter -latterly -least -less -lest -let -let's -like -liked -likely -little -look -looking -looks -ltd -m -mainly -many -may -maybe -me -mean -meanwhile -merely -might -more -moreover -most -mostly -much -must -my -myself -n -name -namely -nd -near -nearly -necessary -need -needs -neither -never -nevertheless -new -next -nine -no -nobody -non -none -noone -nor -normally -not -nothing -novel -now -nowhere -o -obviously -of -off -often -oh -ok -okay -old -on -once -one -ones -only -onto -or -other -others -otherwise -ought -our -ours -ourselves -out -outside -over -overall -own -p -particular -particularly -per -perhaps -placed -please -plus -possible -presumably -probably -provides -q -que -quite -qv -r -rather -rd -re -really -reasonably -regarding -regardless -regards -relatively -respectively -right -s -said -same -saw -say -saying -says -second -secondly -see -seeing -seem -seemed -seeming -seems -seen -self -selves -sensible -sent -serious -seriously -seven -several -shall -she -should -shouldn't -since -six -so -some -somebody -somehow -someone -something -sometime -sometimes -somewhat -somewhere -soon -sorry -specified -specify -specifying -still -sub -such -sup -sure -t -t's -take -taken -tell -tends -th -than -thank -thanks -thanx -that -that's -thats -the -their -theirs -them -themselves -then -thence -there -there's -thereafter -thereby -therefore -therein -theres -thereupon -these -they -they'd -they'll -they're -they've -think -third -this -thorough -thoroughly -those -though -three -through -throughout -thru -thus -to -together -too -took -toward -towards -tried -tries -truly -try -trying -twice -two -u -un -under -unfortunately -unless -unlikely -until -unto -up -upon -us -use -used -useful -uses -using -usually -uucp -v -value -various -very -via -viz -vs -w -want -wants -was -wasn't -way -we -we'd -we'll -we're -we've -welcome -well -went -were -weren't -what -what's -whatever -when -whence -whenever -where -where's -whereafter -whereas -whereby -wherein -whereupon -wherever -whether -which -while -whither -who -who's -whoever -whole -whom -whose -why -will -willing -wish -with -within -without -won't -wonder -would -would -wouldn't -x -y -yes -yet -you -you'd -you'll -you're -you've -your -yours -yourself -yourselves -z +dr +dra +mr +ms +a +a's +able +about +above +according +accordingly +across +actually +after +afterwards +again +against +ain't +all +allow +allows +almost +alone +along +already +also +although +always +am +among +amongst +an +and +another +any +anybody +anyhow +anyone +anything +anyway +anyways +anywhere +apart +appear +appreciate +appropriate +are +aren't +around +as +aside +ask +asking +associated +at +available +away +awfully +b +be +became +because +become +becomes +becoming +been +before +beforehand +behind +being +believe +below +beside +besides +best +better +between +beyond +both +brief +but +by +c +c'mon +c's +came +can +can't +cannot +cant +cause +causes +certain +certainly +changes +clearly +co +com +come +comes +concerning +consequently +consider +considering +contain +containing +contains +corresponding +could +couldn't +course +currently +d +definitely +described +despite +did +didn't +different +do +does +doesn't +doing +don't +done +down +downwards +during +e +each +edu +eg +eight +either +else +elsewhere +enough +entirely +especially +et +etc +even +ever +every +everybody +everyone +everything +everywhere +ex +exactly +example +except +f +far +few +fifth +first +five +followed +following +follows +for +former +formerly +forth +four +from +further +furthermore +g +get +gets +getting +given +gives +go +goes +going +gone +got +gotten +greetings +h +had +hadn't +happens +hardly +has +hasn't +have +haven't +having +he +he's +hello +help +hence +her +here +here's +hereafter +hereby +herein +hereupon +hers +herself +hi +him +himself +his +hither +hopefully +how +howbeit +however +i +i'd +i'll +i'm +i've +ie +if +ignored +immediate +in +inasmuch +inc +indeed +indicate +indicated +indicates +inner +insofar +instead +into +inward +is +isn't +it +it'd +it'll +it's +its +itself +j +just +k +keep +keeps +kept +know +knows +known +l +last +lately +later +latter +latterly +least +less +lest +let +let's +like +liked +likely +little +look +looking +looks +ltd +m +mainly +many +may +maybe +me +mean +meanwhile +merely +might +more +moreover +most +mostly +much +must +my +myself +n +name +namely +nd +near +nearly +necessary +need +needs +neither +never +nevertheless +new +next +nine +no +nobody +non +none +noone +nor +normally +not +nothing +novel +now +nowhere +o +obviously +of +off +often +oh +ok +okay +old +on +once +one +ones +only +onto +or +other +others +otherwise +ought +our +ours +ourselves +out +outside +over +overall +own +p +particular +particularly +per +perhaps +placed +please +plus +possible +presumably +probably +provides +q +que +quite +qv +r +rather +rd +re +really +reasonably +regarding +regardless +regards +relatively +respectively +right +s +said +same +saw +say +saying +says +second +secondly +see +seeing +seem +seemed +seeming +seems +seen +self +selves +sensible +sent +serious +seriously +seven +several +shall +she +should +shouldn't +since +six +so +some +somebody +somehow +someone +something +sometime +sometimes +somewhat +somewhere +soon +sorry +specified +specify +specifying +still +sub +such +sup +sure +t +t's +take +taken +tell +tends +th +than +thank +thanks +thanx +that +that's +thats +the +their +theirs +them +themselves +then +thence +there +there's +thereafter +thereby +therefore +therein +theres +thereupon +these +they +they'd +they'll +they're +they've +think +third +this +thorough +thoroughly +those +though +three +through +throughout +thru +thus +to +together +too +took +toward +towards +tried +tries +truly +try +trying +twice +two +u +un +under +unfortunately +unless +unlikely +until +unto +up +upon +us +use +used +useful +uses +using +usually +uucp +v +value +various +very +via +viz +vs +w +want +wants +was +wasn't +way +we +we'd +we'll +we're +we've +welcome +well +went +were +weren't +what +what's +whatever +when +whence +whenever +where +where's +whereafter +whereas +whereby +wherein +whereupon +wherever +whether +which +while +whither +who +who's +whoever +whole +whom +whose +why +will +willing +wish +with +within +without +won't +wonder +would +would +wouldn't +x +y +yes +yet +you +you'd +you'll +you're +you've +your +yours +yourself +yourselves +z zero \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_es.txt b/yake/core/StopwordsList/stopwords_es.txt similarity index 86% rename from yake/StopwordsList/stopwords_es.txt rename to yake/core/StopwordsList/stopwords_es.txt index 5f3983fc..78e3c411 100644 --- a/yake/StopwordsList/stopwords_es.txt +++ b/yake/core/StopwordsList/stopwords_es.txt @@ -1,351 +1,351 @@ -él -ésta -éstas -éste -éstos -última -últimas -último -últimos -a -añadió -aún -actualmente -adelante -además -afirmó -agregó -ahí -ahora -al -algún -algo -alguna -algunas -alguno -algunos -alrededor -ambos -ante -anterior -antes -apenas -aproximadamente -aquí -así -aseguró -aunque -ayer -bajo -bien -buen -buena -buenas -bueno -buenos -cómo -cada -casi -cerca -cierto -cinco -comentó -como -con -conocer -consideró -considera -contra -cosas -creo -cual -cuales -cualquier -cuando -cuanto -cuatro -cuenta -da -dado -dan -dar -de -debe -deben -debido -decir -dejó -del -demás -dentro -desde -después -dice -dicen -dicho -dieron -diferente -diferentes -dijeron -dijo -dio -donde -dos -durante -e -ejemplo -el -ella -ellas -ello -ellos -embargo -en -encuentra -entonces -entre -era -eran -es -esa -esas -ese -eso -esos -está -están -esta -estaba -estaban -estamos -estar -estará -estas -este -esto -estos -estoy -estuvo -ex -existe -existen -explicó -expresó -fin -fue -fuera -fueron -gran -grandes -ha -había -habían -haber -habrá -hace -hacen -hacer -hacerlo -hacia -haciendo -han -hasta -hay -haya -he -hecho -hemos -hicieron -hizo -hoy -hubo -igual -incluso -indicó -informó -junto -la -lado -las -le -les -llegó -lleva -llevar -lo -los -luego -lugar -más -manera -manifestó -mayor -me -mediante -mejor -mencionó -menos -mi -mientras -misma -mismas -mismo -mismos -momento -mucha -muchas -mucho -muchos -muy -nada -nadie -ni -ningún -ninguna -ningunas -ninguno -ningunos -no -nos -nosotras -nosotros -nuestra -nuestras -nuestro -nuestros -nueva -nuevas -nuevo -nuevos -nunca -o -ocho -otra -otras -otro -otros -para -parece -parte -partir -pasada -pasado -pero -pesar -poca -pocas -poco -pocos -podemos -podrá -podrán -podría -podrían -poner -por -porque -posible -próximo -próximos -primer -primera -primero -primeros -principalmente -propia -propias -propio -propios -pudo -pueda -puede -pueden -pues -qué -que -quedó -queremos -quién -quien -quienes -quiere -realizó -realizado -realizar -respecto -sí -sólo -se -señaló -sea -sean -según -segunda -segundo -seis -ser -será -serán -sería -si -sido -siempre -siendo -siete -sigue -siguiente -sin -sino -sobre -sola -solamente -solas -solo -solos -son -su -sus -tal -también -tampoco -tan -tanto -tenía -tendrá -tendrán -tenemos -tener -tenga -tengo -tenido -tercera -tiene -tienen -toda -todas -todavía -todo -todos -total -tras -trata -través -tres -tuvo -un -una -unas -uno -unos -usted -va -vamos -van -varias -varios -veces -ver -vez -y -ya +él +ésta +éstas +éste +éstos +última +últimas +último +últimos +a +añadió +aún +actualmente +adelante +además +afirmó +agregó +ahí +ahora +al +algún +algo +alguna +algunas +alguno +algunos +alrededor +ambos +ante +anterior +antes +apenas +aproximadamente +aquí +así +aseguró +aunque +ayer +bajo +bien +buen +buena +buenas +bueno +buenos +cómo +cada +casi +cerca +cierto +cinco +comentó +como +con +conocer +consideró +considera +contra +cosas +creo +cual +cuales +cualquier +cuando +cuanto +cuatro +cuenta +da +dado +dan +dar +de +debe +deben +debido +decir +dejó +del +demás +dentro +desde +después +dice +dicen +dicho +dieron +diferente +diferentes +dijeron +dijo +dio +donde +dos +durante +e +ejemplo +el +ella +ellas +ello +ellos +embargo +en +encuentra +entonces +entre +era +eran +es +esa +esas +ese +eso +esos +está +están +esta +estaba +estaban +estamos +estar +estará +estas +este +esto +estos +estoy +estuvo +ex +existe +existen +explicó +expresó +fin +fue +fuera +fueron +gran +grandes +ha +había +habían +haber +habrá +hace +hacen +hacer +hacerlo +hacia +haciendo +han +hasta +hay +haya +he +hecho +hemos +hicieron +hizo +hoy +hubo +igual +incluso +indicó +informó +junto +la +lado +las +le +les +llegó +lleva +llevar +lo +los +luego +lugar +más +manera +manifestó +mayor +me +mediante +mejor +mencionó +menos +mi +mientras +misma +mismas +mismo +mismos +momento +mucha +muchas +mucho +muchos +muy +nada +nadie +ni +ningún +ninguna +ningunas +ninguno +ningunos +no +nos +nosotras +nosotros +nuestra +nuestras +nuestro +nuestros +nueva +nuevas +nuevo +nuevos +nunca +o +ocho +otra +otras +otro +otros +para +parece +parte +partir +pasada +pasado +pero +pesar +poca +pocas +poco +pocos +podemos +podrá +podrán +podría +podrían +poner +por +porque +posible +próximo +próximos +primer +primera +primero +primeros +principalmente +propia +propias +propio +propios +pudo +pueda +puede +pueden +pues +qué +que +quedó +queremos +quién +quien +quienes +quiere +realizó +realizado +realizar +respecto +sí +sólo +se +señaló +sea +sean +según +segunda +segundo +seis +ser +será +serán +sería +si +sido +siempre +siendo +siete +sigue +siguiente +sin +sino +sobre +sola +solamente +solas +solo +solos +son +su +sus +tal +también +tampoco +tan +tanto +tenía +tendrá +tendrán +tenemos +tener +tenga +tengo +tenido +tercera +tiene +tienen +toda +todas +todavía +todo +todos +total +tras +trata +través +tres +tuvo +un +una +unas +uno +unos +usted +va +vamos +van +varias +varios +veces +ver +vez +y +ya yo \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_et.txt b/yake/core/StopwordsList/stopwords_et.txt similarity index 81% rename from yake/StopwordsList/stopwords_et.txt rename to yake/core/StopwordsList/stopwords_et.txt index 8e774ef3..8b5d74e5 100644 --- a/yake/StopwordsList/stopwords_et.txt +++ b/yake/core/StopwordsList/stopwords_et.txt @@ -1,35 +1,35 @@ -aga -ei -et -ja -jah -kas -kui -kõik -ma -me -mida -midagi -mind -minu -mis -mu -mul -mulle -nad -nii -oled -olen -oli -oma -on -pole -sa -seda -see -selle -siin -siis -ta -te +aga +ei +et +ja +jah +kas +kui +kõik +ma +me +mida +midagi +mind +minu +mis +mu +mul +mulle +nad +nii +oled +olen +oli +oma +on +pole +sa +seda +see +selle +siin +siis +ta +te ära \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_fa.txt b/yake/core/StopwordsList/stopwords_fa.txt similarity index 89% rename from yake/StopwordsList/stopwords_fa.txt rename to yake/core/StopwordsList/stopwords_fa.txt index a9347060..109b54c3 100644 --- a/yake/StopwordsList/stopwords_fa.txt +++ b/yake/core/StopwordsList/stopwords_fa.txt @@ -1,332 +1,332 @@ -Ùˆ -در -به -از -كه -مي -اين -است -را -با -هاي -براي -آن -يك -شود -شده -خود -ها -كرد -شد -اي -تا -كند -بر -بود -Ú¯ÙØª -نيز -وي -هم -كنند -دارد -ما -كرده -يا -اما -بايد -دو -اند -هر -خواهد -او -مورد -آنها -باشد -ديگر -مردم -نمي -بين -پيش -پس -اگر -همه -صورت -يكي -هستند -بي -من -دهد -هزار -نيست -Ø§Ø³ØªÙØ§Ø¯Ù‡ -داد -داشته -راه -داشت -Ú†Ù‡ -همچنين -كردند -داده -بوده -دارند -همين -ميليون -سوي -شوند -بيشتر -بسيار -روي -Ú¯Ø±ÙØªÙ‡ -هايي -تواند -اول -نام -هيچ -چند -جديد -بيش -شدن -كردن -كنيم -نشان -حتي -اينكه -ولی -توسط -چنين -برخي -نه -ديروز -دوم -درباره -بعد -مختل٠-گيرد -شما -Ú¯ÙØªÙ‡ -آنان -بار -طور -Ú¯Ø±ÙØª -دهند -گذاري -بسياري -طي -بودند -ميليارد -بدون -تمام -كل -تر -براساس -شدند -ترين -امروز -باشند -ندارد -چون -قابل -گويد -ديگري -همان -خواهند -قبل -آمده -اكنون -تحت -طريق -گيري -جاي -هنوز -چرا -البته -كنيد -سازي -سوم -كنم -بلكه -زير -توانند -ضمن -Ùقط -بودن -حق -آيد -وقتي -اش -يابد -نخستين -مقابل -خدمات -امسال -تاكنون -مانند -تازه -آورد -Ùكر -آنچه -نخست -نشده -شايد -چهار -جريان -پنج -ساخته -زيرا -نزديك -برداري -كسي -ريزي -Ø±ÙØª -گردد -مثل -آمد -ام -بهترين -دانست -كمتر -دادن -تمامي -جلوگيري -بيشتري -ايم -ناشي -چيزي -آنكه -بالا -بنابراين -ايشان -بعضي -دادند -داشتند -برخوردار -نخواهد -هنگام -نبايد -غير -نبود -ديده -ÙˆÚ¯Ùˆ -داريم -چگونه -بندي -خواست -Ùوق -ده -نوعي -هستيم -ديگران -همچنان -سراسر -ندارند -گروهي -سعي -روزهاي -آنجا -يكديگر -كردم -بيست -بروز -سپس -Ø±ÙØªÙ‡ -آورده -نمايد -باشيم -گويند -زياد -خويش -همواره -گذاشته -شش -نداشته -شناسي -خواهيم -آباد -داشتن -نظير -همچون -باره -نكرده -شان -سابق -Ù‡ÙØª -دانند -جايي -بی -جز -زیر٠-روی٠-سری٠-توی٠-جلوی٠-پیش٠-عقب٠-بالای٠-خارج٠-وسط٠-بیرون٠-سوی٠-کنار٠-پاعین٠-نزد٠-نزدیک٠-دنبال٠-حدود٠-برابر٠-طبق٠-مانند٠-ضدّ٠-هنگام٠-برای٠-مثل٠-بارة -اثر٠-تول٠-علّت٠-سمت٠-عنوان٠-قصد٠-روب -جدا -Ú©ÛŒ -Ú©Ù‡ -چیست -هست -کجا -کجاست -Ú©ÙŽÛŒ -چطور -کدام -آیا -مگر -چندین -یک -چیزی -دیگر -کسی -بعری -هیچ -چیز -جا -کس -هرگز -یا -تنها -بلکه -خیاه -بله -بلی -آره -آری -مرسی -البتّه -Ù„Ø·ÙØ§Ù‹ -ّه -انکه -وقتیکه -همین -پیش -مدّتی -هنگامی -مان -تان +Ùˆ +در +به +از +كه +مي +اين +است +را +با +هاي +براي +آن +يك +شود +شده +خود +ها +كرد +شد +اي +تا +كند +بر +بود +Ú¯ÙØª +نيز +وي +هم +كنند +دارد +ما +كرده +يا +اما +بايد +دو +اند +هر +خواهد +او +مورد +آنها +باشد +ديگر +مردم +نمي +بين +پيش +پس +اگر +همه +صورت +يكي +هستند +بي +من +دهد +هزار +نيست +Ø§Ø³ØªÙØ§Ø¯Ù‡ +داد +داشته +راه +داشت +Ú†Ù‡ +همچنين +كردند +داده +بوده +دارند +همين +ميليون +سوي +شوند +بيشتر +بسيار +روي +Ú¯Ø±ÙØªÙ‡ +هايي +تواند +اول +نام +هيچ +چند +جديد +بيش +شدن +كردن +كنيم +نشان +حتي +اينكه +ولی +توسط +چنين +برخي +نه +ديروز +دوم +درباره +بعد +مختل٠+گيرد +شما +Ú¯ÙØªÙ‡ +آنان +بار +طور +Ú¯Ø±ÙØª +دهند +گذاري +بسياري +طي +بودند +ميليارد +بدون +تمام +كل +تر +براساس +شدند +ترين +امروز +باشند +ندارد +چون +قابل +گويد +ديگري +همان +خواهند +قبل +آمده +اكنون +تحت +طريق +گيري +جاي +هنوز +چرا +البته +كنيد +سازي +سوم +كنم +بلكه +زير +توانند +ضمن +Ùقط +بودن +حق +آيد +وقتي +اش +يابد +نخستين +مقابل +خدمات +امسال +تاكنون +مانند +تازه +آورد +Ùكر +آنچه +نخست +نشده +شايد +چهار +جريان +پنج +ساخته +زيرا +نزديك +برداري +كسي +ريزي +Ø±ÙØª +گردد +مثل +آمد +ام +بهترين +دانست +كمتر +دادن +تمامي +جلوگيري +بيشتري +ايم +ناشي +چيزي +آنكه +بالا +بنابراين +ايشان +بعضي +دادند +داشتند +برخوردار +نخواهد +هنگام +نبايد +غير +نبود +ديده +ÙˆÚ¯Ùˆ +داريم +چگونه +بندي +خواست +Ùوق +ده +نوعي +هستيم +ديگران +همچنان +سراسر +ندارند +گروهي +سعي +روزهاي +آنجا +يكديگر +كردم +بيست +بروز +سپس +Ø±ÙØªÙ‡ +آورده +نمايد +باشيم +گويند +زياد +خويش +همواره +گذاشته +شش +نداشته +شناسي +خواهيم +آباد +داشتن +نظير +همچون +باره +نكرده +شان +سابق +Ù‡ÙØª +دانند +جايي +بی +جز +زیر٠+روی٠+سری٠+توی٠+جلوی٠+پیش٠+عقب٠+بالای٠+خارج٠+وسط٠+بیرون٠+سوی٠+کنار٠+پاعین٠+نزد٠+نزدیک٠+دنبال٠+حدود٠+برابر٠+طبق٠+مانند٠+ضدّ٠+هنگام٠+برای٠+مثل٠+بارة +اثر٠+تول٠+علّت٠+سمت٠+عنوان٠+قصد٠+روب +جدا +Ú©ÛŒ +Ú©Ù‡ +چیست +هست +کجا +کجاست +Ú©ÙŽÛŒ +چطور +کدام +آیا +مگر +چندین +یک +چیزی +دیگر +کسی +بعری +هیچ +چیز +جا +کس +هرگز +یا +تنها +بلکه +خیاه +بله +بلی +آره +آری +مرسی +البتّه +Ù„Ø·ÙØ§Ù‹ +ّه +انکه +وقتیکه +همین +پیش +مدّتی +هنگامی +مان +تان diff --git a/yake/StopwordsList/stopwords_fi.txt b/yake/core/StopwordsList/stopwords_fi.txt similarity index 88% rename from yake/StopwordsList/stopwords_fi.txt rename to yake/core/StopwordsList/stopwords_fi.txt index 6b9afbb1..c5a12ba2 100644 --- a/yake/StopwordsList/stopwords_fi.txt +++ b/yake/core/StopwordsList/stopwords_fi.txt @@ -1,747 +1,747 @@ -aiemmin -aika -aikaa -aikaan -aikaisemmin -aikaisin -aikajen -aikana -aikoina -aikoo -aikovat -aina -ainakaan -ainakin -ainoa -ainoat -aiomme -aion -aiotte -aist -aivan -ajan -älä -alas -alemmas -älköön -alkuisin -alkuun -alla -alle -aloitamme -aloitan -aloitat -aloitatte -aloitattivat -aloitettava -aloitettevaksi -aloitettu -aloitimme -aloitin -aloitit -aloititte -aloittaa -aloittamatta -aloitti -aloittivat -alta -aluksi -alussa -alusta -annettavaksi -annetteva -annettu -antaa -antamatta -antoi -aoua -apu -asia -asiaa -asian -asiasta -asiat -asioiden -asioihin -asioita -asti -avuksi -avulla -avun -avutta -edellä -edelle -edelleen -edeltä -edemmäs -edes -edessä -edestä -ehkä -ei -eikä -eilen -eivät -eli -ellei -elleivät -ellemme -ellen -ellet -ellette -emme -en -enää -enemmän -eniten -ennen -ensi -ensimmäinen -ensimmäiseksi -ensimmäisen -ensimmäisenä -ensimmäiset -ensimmäisiä -ensimmäisiksi -ensimmäisinä -ensimmäistä -ensin -entinen -entisen -entisiä -entistä -entisten -eräät -eräiden -eräs -eri -erittäin -erityisesti -esi -esiin -esillä -esimerkiksi -et -eteen -etenkin -että -ette -ettei -halua -haluaa -haluamatta -haluamme -haluan -haluat -haluatte -haluavat -halunnut -halusi -halusimme -halusin -halusit -halusitte -halusivat -halutessa -haluton -hän -häneen -hänellä -hänelle -häneltä -hänen -hänessä -hänestä -hänet -he -hei -heidän -heihin -heille -heiltä -heissä -heistä -heitä -helposti -heti -hetkellä -hieman -huolimatta -huomenna -hyvä -hyvää -hyvät -hyviä -hyvien -hyviin -hyviksi -hyville -hyviltä -hyvin -hyvinä -hyvissä -hyvistä -ihan -ilman -ilmeisesti -itse -itseään -itsensä -ja -jää -jälkeen -jälleen -jo -johon -joiden -joihin -joiksi -joilla -joille -joilta -joissa -joista -joita -joka -jokainen -jokin -joko -joku -jolla -jolle -jolloin -jolta -jompikumpi -jonka -jonkin -jonne -joo -jopa -jos -joskus -jossa -josta -jota -jotain -joten -jotenkin -jotenkuten -jotka -jotta -jouduimme -jouduin -jouduit -jouduitte -joudumme -joudun -joudutte -joukkoon -joukossa -joukosta -joutua -joutui -joutuivat -joutumaan -joutuu -joutuvat -juuri -kahdeksan -kahdeksannen -kahdella -kahdelle -kahdelta -kahden -kahdessa -kahdesta -kahta -kahteen -kai -kaiken -kaikille -kaikilta -kaikkea -kaikki -kaikkia -kaikkiaan -kaikkialla -kaikkialle -kaikkialta -kaikkien -kaikkin -kaksi -kannalta -kannattaa -kanssa -kanssaan -kanssamme -kanssani -kanssanne -kanssasi -kauan -kauemmas -kautta -kehen -keiden -keihin -keiksi -keillä -keille -keiltä -keinä -keissä -keistä -keitä -keittä -keitten -keneen -keneksi -kenellä -kenelle -keneltä -kenen -kenenä -kenessä -kenestä -kenet -kenettä -kennessästä -kerran -kerta -kertaa -kesken -keskimäärin -ketä -ketkä -kiitos -kohti -koko -kokonaan -kolmas -kolme -kolmen -kolmesti -koska -koskaan -kovin -kuin -kuinka -kuitenkaan -kuitenkin -kuka -kukaan -kukin -kumpainen -kumpainenkaan -kumpi -kumpikaan -kumpikin -kun -kuten -kuuden -kuusi -kuutta -kyllä -kymmenen -kyse -lähekkäin -lähellä -lähelle -läheltä -lähemmäs -lähes -lähinnä -lähtien -läpi -liian -liki -lisää -lisäksi -luo -mahdollisimman -mahdollista -me -meidän -meillä -meille -melkein -melko -menee -meneet -menemme -menen -menet -menette -menevät -meni -menimme -menin -menit -menivät -mennessä -mennyt -menossa -mihin -mikä -mikään -mikäli -mikin -miksi -milloin -minä -minne -minun -minut -missä -mistä -mitä -mitään -miten -moi -molemmat -mones -monesti -monet -moni -moniaalla -moniaalle -moniaalta -monta -muassa -muiden -muita -muka -mukaan -mukaansa -mukana -mutta -muu -muualla -muualle -muualta -muuanne -muulloin -muun -muut -muuta -muutama -muutaman -muuten -myöhemmin -myös -myöskään -myöskin -myötä -näiden -näin -näissä -näissähin -näissälle -näissältä -näissästä -näitä -nämä -ne -neljä -neljää -neljän -niiden -niin -niistä -niitä -noin -nopeammin -nopeasti -nopeiten -nro -nuo -nyt -ohi -oikein -ole -olemme -olen -olet -olette -oleva -olevan -olevat -oli -olimme -olin -olisi -olisimme -olisin -olisit -olisitte -olisivat -olit -olitte -olivat -olla -olleet -olli -ollut -oma -omaa -omaan -omaksi -omalle -omalta -oman -omassa -omat -omia -omien -omiin -omiksi -omille -omilta -omissa -omista -on -onkin -onko -ovat -päälle -paikoittain -paitsi -pakosti -paljon -paremmin -parempi -parhaillaan -parhaiten -peräti -perusteella -pian -pieneen -pieneksi -pienellä -pienelle -pieneltä -pienempi -pienestä -pieni -pienin -puolesta -puolestaan -runsaasti -saakka -sadam -sama -samaa -samaan -samalla -samallalta -samallassa -samallasta -saman -samat -samoin -sata -sataa -satojen -se -seitsemän -sekä -sen -seuraavat -siellä -sieltä -siihen -siinä -siis -siitä -sijaan -siksi -sillä -silloin -silti -sinä -sinne -sinua -sinulle -sinulta -sinun -sinussa -sinusta -sinut -sisäkkäin -sisällä -sitä -siten -sitten -suoraan -suuntaan -suuren -suuret -suuri -suuria -suurin -suurten -taa -täällä -täältä -taas -taemmas -tähän -tahansa -tai -takaa -takaisin -takana -takia -tällä -tällöin -tämä -tämän -tänä -tänään -tänne -tapauksessa -tässä -tästä -tätä -täten -tavalla -tavoitteena -täysin -täytyvät -täytyy -te -tietysti -todella -toinen -toisaalla -toisaalle -toisaalta -toiseen -toiseksi -toisella -toiselle -toiselta -toisemme -toisen -toisensa -toisessa -toisesta -toista -toistaiseksi -toki -tosin -tuhannen -tuhat -tule -tulee -tulemme -tulen -tulet -tulette -tulevat -tulimme -tulin -tulisi -tulisimme -tulisin -tulisit -tulisitte -tulisivat -tulit -tulitte -tulivat -tulla -tulleet -tullut -tuntuu -tuo -tuolla -tuolloin -tuolta -tuonne -tuskin -tykö -usea -useasti -useimmiten -usein -useita -uudeksi -uudelleen -uuden -uudet -uusi -uusia -uusien -uusinta -uuteen -uutta -vaan -vähän -vähemmän -vähintään -vähiten -vai -vaiheessa -vaikea -vaikean -vaikeat -vaikeilla -vaikeille -vaikeilta -vaikeissa -vaikeista -vaikka -vain -välillä -varmasti -varsin -varsinkin -varten -vasta -vastaan -vastakkain -verran -vielä -vierekkäin -vieri -viiden -viime -viimeinen -viimeisen -viimeksi -viisi -voi -voidaan -voimme -voin -voisi -voit -voitte -voivat -vuoden -vuoksi -vuosi -vuosien -vuosina -vuotta -yhä -yhdeksän -yhden -yhdessä -yhtä -yhtäällä -yhtäälle -yhtäältä -yhtään -yhteen -yhteensä -yhteydessä -yhteyteen -yksi -yksin -yksittäin -yleensä -ylemmäs -yli -ylös +aiemmin +aika +aikaa +aikaan +aikaisemmin +aikaisin +aikajen +aikana +aikoina +aikoo +aikovat +aina +ainakaan +ainakin +ainoa +ainoat +aiomme +aion +aiotte +aist +aivan +ajan +älä +alas +alemmas +älköön +alkuisin +alkuun +alla +alle +aloitamme +aloitan +aloitat +aloitatte +aloitattivat +aloitettava +aloitettevaksi +aloitettu +aloitimme +aloitin +aloitit +aloititte +aloittaa +aloittamatta +aloitti +aloittivat +alta +aluksi +alussa +alusta +annettavaksi +annetteva +annettu +antaa +antamatta +antoi +aoua +apu +asia +asiaa +asian +asiasta +asiat +asioiden +asioihin +asioita +asti +avuksi +avulla +avun +avutta +edellä +edelle +edelleen +edeltä +edemmäs +edes +edessä +edestä +ehkä +ei +eikä +eilen +eivät +eli +ellei +elleivät +ellemme +ellen +ellet +ellette +emme +en +enää +enemmän +eniten +ennen +ensi +ensimmäinen +ensimmäiseksi +ensimmäisen +ensimmäisenä +ensimmäiset +ensimmäisiä +ensimmäisiksi +ensimmäisinä +ensimmäistä +ensin +entinen +entisen +entisiä +entistä +entisten +eräät +eräiden +eräs +eri +erittäin +erityisesti +esi +esiin +esillä +esimerkiksi +et +eteen +etenkin +että +ette +ettei +halua +haluaa +haluamatta +haluamme +haluan +haluat +haluatte +haluavat +halunnut +halusi +halusimme +halusin +halusit +halusitte +halusivat +halutessa +haluton +hän +häneen +hänellä +hänelle +häneltä +hänen +hänessä +hänestä +hänet +he +hei +heidän +heihin +heille +heiltä +heissä +heistä +heitä +helposti +heti +hetkellä +hieman +huolimatta +huomenna +hyvä +hyvää +hyvät +hyviä +hyvien +hyviin +hyviksi +hyville +hyviltä +hyvin +hyvinä +hyvissä +hyvistä +ihan +ilman +ilmeisesti +itse +itseään +itsensä +ja +jää +jälkeen +jälleen +jo +johon +joiden +joihin +joiksi +joilla +joille +joilta +joissa +joista +joita +joka +jokainen +jokin +joko +joku +jolla +jolle +jolloin +jolta +jompikumpi +jonka +jonkin +jonne +joo +jopa +jos +joskus +jossa +josta +jota +jotain +joten +jotenkin +jotenkuten +jotka +jotta +jouduimme +jouduin +jouduit +jouduitte +joudumme +joudun +joudutte +joukkoon +joukossa +joukosta +joutua +joutui +joutuivat +joutumaan +joutuu +joutuvat +juuri +kahdeksan +kahdeksannen +kahdella +kahdelle +kahdelta +kahden +kahdessa +kahdesta +kahta +kahteen +kai +kaiken +kaikille +kaikilta +kaikkea +kaikki +kaikkia +kaikkiaan +kaikkialla +kaikkialle +kaikkialta +kaikkien +kaikkin +kaksi +kannalta +kannattaa +kanssa +kanssaan +kanssamme +kanssani +kanssanne +kanssasi +kauan +kauemmas +kautta +kehen +keiden +keihin +keiksi +keillä +keille +keiltä +keinä +keissä +keistä +keitä +keittä +keitten +keneen +keneksi +kenellä +kenelle +keneltä +kenen +kenenä +kenessä +kenestä +kenet +kenettä +kennessästä +kerran +kerta +kertaa +kesken +keskimäärin +ketä +ketkä +kiitos +kohti +koko +kokonaan +kolmas +kolme +kolmen +kolmesti +koska +koskaan +kovin +kuin +kuinka +kuitenkaan +kuitenkin +kuka +kukaan +kukin +kumpainen +kumpainenkaan +kumpi +kumpikaan +kumpikin +kun +kuten +kuuden +kuusi +kuutta +kyllä +kymmenen +kyse +lähekkäin +lähellä +lähelle +läheltä +lähemmäs +lähes +lähinnä +lähtien +läpi +liian +liki +lisää +lisäksi +luo +mahdollisimman +mahdollista +me +meidän +meillä +meille +melkein +melko +menee +meneet +menemme +menen +menet +menette +menevät +meni +menimme +menin +menit +menivät +mennessä +mennyt +menossa +mihin +mikä +mikään +mikäli +mikin +miksi +milloin +minä +minne +minun +minut +missä +mistä +mitä +mitään +miten +moi +molemmat +mones +monesti +monet +moni +moniaalla +moniaalle +moniaalta +monta +muassa +muiden +muita +muka +mukaan +mukaansa +mukana +mutta +muu +muualla +muualle +muualta +muuanne +muulloin +muun +muut +muuta +muutama +muutaman +muuten +myöhemmin +myös +myöskään +myöskin +myötä +näiden +näin +näissä +näissähin +näissälle +näissältä +näissästä +näitä +nämä +ne +neljä +neljää +neljän +niiden +niin +niistä +niitä +noin +nopeammin +nopeasti +nopeiten +nro +nuo +nyt +ohi +oikein +ole +olemme +olen +olet +olette +oleva +olevan +olevat +oli +olimme +olin +olisi +olisimme +olisin +olisit +olisitte +olisivat +olit +olitte +olivat +olla +olleet +olli +ollut +oma +omaa +omaan +omaksi +omalle +omalta +oman +omassa +omat +omia +omien +omiin +omiksi +omille +omilta +omissa +omista +on +onkin +onko +ovat +päälle +paikoittain +paitsi +pakosti +paljon +paremmin +parempi +parhaillaan +parhaiten +peräti +perusteella +pian +pieneen +pieneksi +pienellä +pienelle +pieneltä +pienempi +pienestä +pieni +pienin +puolesta +puolestaan +runsaasti +saakka +sadam +sama +samaa +samaan +samalla +samallalta +samallassa +samallasta +saman +samat +samoin +sata +sataa +satojen +se +seitsemän +sekä +sen +seuraavat +siellä +sieltä +siihen +siinä +siis +siitä +sijaan +siksi +sillä +silloin +silti +sinä +sinne +sinua +sinulle +sinulta +sinun +sinussa +sinusta +sinut +sisäkkäin +sisällä +sitä +siten +sitten +suoraan +suuntaan +suuren +suuret +suuri +suuria +suurin +suurten +taa +täällä +täältä +taas +taemmas +tähän +tahansa +tai +takaa +takaisin +takana +takia +tällä +tällöin +tämä +tämän +tänä +tänään +tänne +tapauksessa +tässä +tästä +tätä +täten +tavalla +tavoitteena +täysin +täytyvät +täytyy +te +tietysti +todella +toinen +toisaalla +toisaalle +toisaalta +toiseen +toiseksi +toisella +toiselle +toiselta +toisemme +toisen +toisensa +toisessa +toisesta +toista +toistaiseksi +toki +tosin +tuhannen +tuhat +tule +tulee +tulemme +tulen +tulet +tulette +tulevat +tulimme +tulin +tulisi +tulisimme +tulisin +tulisit +tulisitte +tulisivat +tulit +tulitte +tulivat +tulla +tulleet +tullut +tuntuu +tuo +tuolla +tuolloin +tuolta +tuonne +tuskin +tykö +usea +useasti +useimmiten +usein +useita +uudeksi +uudelleen +uuden +uudet +uusi +uusia +uusien +uusinta +uuteen +uutta +vaan +vähän +vähemmän +vähintään +vähiten +vai +vaiheessa +vaikea +vaikean +vaikeat +vaikeilla +vaikeille +vaikeilta +vaikeissa +vaikeista +vaikka +vain +välillä +varmasti +varsin +varsinkin +varten +vasta +vastaan +vastakkain +verran +vielä +vierekkäin +vieri +viiden +viime +viimeinen +viimeisen +viimeksi +viisi +voi +voidaan +voimme +voin +voisi +voit +voitte +voivat +vuoden +vuoksi +vuosi +vuosien +vuosina +vuotta +yhä +yhdeksän +yhden +yhdessä +yhtä +yhtäällä +yhtäälle +yhtäältä +yhtään +yhteen +yhteensä +yhteydessä +yhteyteen +yksi +yksin +yksittäin +yleensä +ylemmäs +yli +ylös ympäri \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_fr.txt b/yake/core/StopwordsList/stopwords_fr.txt similarity index 86% rename from yake/StopwordsList/stopwords_fr.txt rename to yake/core/StopwordsList/stopwords_fr.txt index f6e87b55..a953b9d4 100644 --- a/yake/StopwordsList/stopwords_fr.txt +++ b/yake/core/StopwordsList/stopwords_fr.txt @@ -1,463 +1,463 @@ -a -à -â -abord -afin -ah -ai -aie -ainsi -allaient -allo -allô -allons -après -assez -attendu -au -aucun -aucune -aujourd -aujourd'hui -auquel -aura -auront -aussi -autre -autres -aux -auxquelles -auxquels -avaient -avais -avait -avant -avec -avoir -ayant -b -bah -beaucoup -bien -bigre -boum -bravo -brrr -c -ça -car -ce -ceci -cela -celle -celle-ci -celle-là -celles -celles-ci -celles-là -celui -celui-ci -celui-là -cent -cependant -certain -certaine -certaines -certains -certes -ces -cet -cette -ceux -ceux-ci -ceux-là -chacun -chaque -cher -chère -chères -chers -chez -chiche -chut -ci -cinq -cinquantaine -cinquante -cinquantième -cinquième -clac -clic -combien -comme -comment -compris -concernant -contre -couic -crac -d -da -dans -de -debout -dedans -dehors -delà -depuis -derrière -des -dès -désormais -desquelles -desquels -dessous -dessus -deux -deuxième -deuxièmement -devant -devers -devra -différent -différente -différentes -différents -dire -divers -diverse -diverses -dix -dix-huit -dixième -dix-neuf -dix-sept -doit -doivent -donc -dont -douze -douzième -dring -du -duquel -durant -e -effet -eh -elle -elle-même -elles -elles-mêmes -en -encore -entre -envers -environ -es -ès -est -et -etant -étaient -étais -était -étant -etc -été -etre -être -eu -euh -eux -eux-mêmes -excepté -f -façon -fais -faisaient -faisant -fait -feront -fi -flac -floc -font -g -gens -h -ha -hé -hein -hélas -hem -hep -hi -ho -holà -hop -hormis -hors -hou -houp -hue -hui -huit -huitième -hum -hurrah -i -il -ils -importe -j -je -jusqu -jusque -k -l -la -là -laquelle -las -le -lequel -les -lès -lesquelles -lesquels -leur -leurs -longtemps -lorsque -lui -lui-même -m -ma -maint -mais -malgré -me -même -mêmes -merci -mes -mien -mienne -miennes -miens -mille -mince -moi -moi-même -moins -mon -moyennant -n -na -ne -néanmoins -neuf -neuvième -ni -nombreuses -nombreux -non -nos -notre -nôtre -nôtres -nous -nous-mêmes -nul -o -o| -ô -oh -ohé -olé -ollé -on -ont -onze -onzième -ore -ou -où -ouf -ouias -oust -ouste -outre -p -paf -pan -par -parmi -partant -particulier -particulière -particulièrement -pas -passé -pendant -personne -peu -peut -peuvent -peux -pff -pfft -pfut -pif -plein -plouf -plus -plusieurs -plutôt -pouah -pour -pourquoi -premier -première -premièrement -près -proche -psitt -puisque -q -qu -quand -quant -quanta -quant-à-soi -quarante -quatorze -quatre -quatre-vingt -quatrième -quatrièmement -que -quel -quelconque -quelle -quelles -quelque -quelques -quelqu'un -quels -qui -quiconque -quinze -quoi -quoique -r -revoici -revoilà -rien -s -sa -sacrebleu -sans -sapristi -sauf -se -seize -selon -sept -septième -sera -seront -ses -si -sien -sienne -siennes -siens -sinon -six -sixième -soi -soi-même -soit -soixante -son -sont -sous -stop -suis -suivant -sur -surtout -t -ta -tac -tant -te -té -tel -telle -tellement -telles -tels -tenant -tes -tic -tien -tienne -tiennes -tiens -toc -toi -toi-même -ton -touchant -toujours -tous -tout -toute -toutes -treize -trente -très -trois -troisième -troisièmement -trop -tsoin -tsouin -tu -u -un -une -unes -uns -v -va -vais -vas -vé -vers -via -vif -vifs -vingt -vivat -vive -vives -vlan -voici -voilà -vont -vos -votre -vôtre -vôtres -vous -vous-mêmes -vu -w -x -y -z +a +à +â +abord +afin +ah +ai +aie +ainsi +allaient +allo +allô +allons +après +assez +attendu +au +aucun +aucune +aujourd +aujourd'hui +auquel +aura +auront +aussi +autre +autres +aux +auxquelles +auxquels +avaient +avais +avait +avant +avec +avoir +ayant +b +bah +beaucoup +bien +bigre +boum +bravo +brrr +c +ça +car +ce +ceci +cela +celle +celle-ci +celle-là +celles +celles-ci +celles-là +celui +celui-ci +celui-là +cent +cependant +certain +certaine +certaines +certains +certes +ces +cet +cette +ceux +ceux-ci +ceux-là +chacun +chaque +cher +chère +chères +chers +chez +chiche +chut +ci +cinq +cinquantaine +cinquante +cinquantième +cinquième +clac +clic +combien +comme +comment +compris +concernant +contre +couic +crac +d +da +dans +de +debout +dedans +dehors +delà +depuis +derrière +des +dès +désormais +desquelles +desquels +dessous +dessus +deux +deuxième +deuxièmement +devant +devers +devra +différent +différente +différentes +différents +dire +divers +diverse +diverses +dix +dix-huit +dixième +dix-neuf +dix-sept +doit +doivent +donc +dont +douze +douzième +dring +du +duquel +durant +e +effet +eh +elle +elle-même +elles +elles-mêmes +en +encore +entre +envers +environ +es +ès +est +et +etant +étaient +étais +était +étant +etc +été +etre +être +eu +euh +eux +eux-mêmes +excepté +f +façon +fais +faisaient +faisant +fait +feront +fi +flac +floc +font +g +gens +h +ha +hé +hein +hélas +hem +hep +hi +ho +holà +hop +hormis +hors +hou +houp +hue +hui +huit +huitième +hum +hurrah +i +il +ils +importe +j +je +jusqu +jusque +k +l +la +là +laquelle +las +le +lequel +les +lès +lesquelles +lesquels +leur +leurs +longtemps +lorsque +lui +lui-même +m +ma +maint +mais +malgré +me +même +mêmes +merci +mes +mien +mienne +miennes +miens +mille +mince +moi +moi-même +moins +mon +moyennant +n +na +ne +néanmoins +neuf +neuvième +ni +nombreuses +nombreux +non +nos +notre +nôtre +nôtres +nous +nous-mêmes +nul +o +o| +ô +oh +ohé +olé +ollé +on +ont +onze +onzième +ore +ou +où +ouf +ouias +oust +ouste +outre +p +paf +pan +par +parmi +partant +particulier +particulière +particulièrement +pas +passé +pendant +personne +peu +peut +peuvent +peux +pff +pfft +pfut +pif +plein +plouf +plus +plusieurs +plutôt +pouah +pour +pourquoi +premier +première +premièrement +près +proche +psitt +puisque +q +qu +quand +quant +quanta +quant-à-soi +quarante +quatorze +quatre +quatre-vingt +quatrième +quatrièmement +que +quel +quelconque +quelle +quelles +quelque +quelques +quelqu'un +quels +qui +quiconque +quinze +quoi +quoique +r +revoici +revoilà +rien +s +sa +sacrebleu +sans +sapristi +sauf +se +seize +selon +sept +septième +sera +seront +ses +si +sien +sienne +siennes +siens +sinon +six +sixième +soi +soi-même +soit +soixante +son +sont +sous +stop +suis +suivant +sur +surtout +t +ta +tac +tant +te +té +tel +telle +tellement +telles +tels +tenant +tes +tic +tien +tienne +tiennes +tiens +toc +toi +toi-même +ton +touchant +toujours +tous +tout +toute +toutes +treize +trente +très +trois +troisième +troisièmement +trop +tsoin +tsouin +tu +u +un +une +unes +uns +v +va +vais +vas +vé +vers +via +vif +vifs +vingt +vivat +vive +vives +vlan +voici +voilà +vont +vos +votre +vôtre +vôtres +vous +vous-mêmes +vu +w +x +y +z zut \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_hi.txt b/yake/core/StopwordsList/stopwords_hi.txt similarity index 92% rename from yake/StopwordsList/stopwords_hi.txt rename to yake/core/StopwordsList/stopwords_hi.txt index 8cab47ca..2306826a 100644 --- a/yake/StopwordsList/stopwords_hi.txt +++ b/yake/core/StopwordsList/stopwords_hi.txt @@ -1,163 +1,163 @@ -पर -इन -वह -यिह -वà¥à¤¹ -जिनà¥à¤¹à¥‡à¤‚ -जिनà¥à¤¹à¥‹à¤‚ -तिनà¥à¤¹à¥‡à¤‚ -तिनà¥à¤¹à¥‹à¤‚ -किनà¥à¤¹à¥‹à¤‚ -किनà¥à¤¹à¥‡à¤‚ -इतà¥à¤¯à¤¾à¤¦à¤¿ -दà¥à¤µà¤¾à¤°à¤¾ -इनà¥à¤¹à¥‡à¤‚ -इनà¥à¤¹à¥‹à¤‚ -उनà¥à¤¹à¥‹à¤‚ -बिलकà¥à¤² -निहायत -ऱà¥à¤µà¤¾à¤¸à¤¾ -इनà¥à¤¹à¥€à¤‚ -उनà¥à¤¹à¥€à¤‚ -उनà¥à¤¹à¥‡à¤‚ -इसमें -जितना -दà¥à¤¸à¤°à¤¾ -कितना -दबारा -साबà¥à¤¤ -वग़ैरह -दूसरे -कौनसा -लेकिन -होता -करने -किया -लिये -अपने -नहीं -दिया -इसका -करना -वाले -सकते -इसके -सबसे -होने -करते -बहà¥à¤¤ -वरà¥à¤— -करें -होती -अपनी -उनके -कहते -होते -करता -उनकी -इसकी -सकता -रखें -अपना -उसके -जिसे -तिसे -किसे -किसी -काफ़ी -पहले -नीचे -बाला -यहाठ-जैसा -जैसे -मानो -अंदर -भीतर -पूरा -सारा -होना -उनको -वहाठ-वहीं -जहाठ-जीधर -उनका -इनका -के -हैं -गया -बनी -à¤à¤µà¤‚ -हà¥à¤† -साथ -बाद -लिठ-कà¥à¤› -कहा -यदि -हà¥à¤ˆ -इसे -हà¥à¤ -अभी -सभी -कà¥à¤² -रहा -रहे -इसी -उसे -जिस -जिन -तिस -तिन -कौन -किस -कोई -à¤à¤¸à¥‡ -तरह -किर -साभ -संग -यही -बही -उसी -फिर -मगर -का -à¤à¤• -यह -से -को -इस -कि -जो -कर -मे -ने -तो -ही -या -हो -था -तक -आप -ये -थे -दो -वे -थी -जा -ना -उस -à¤à¤¸ -पे -उन -सो -भी -और -घर -तब -जब -अत -व +पर +इन +वह +यिह +वà¥à¤¹ +जिनà¥à¤¹à¥‡à¤‚ +जिनà¥à¤¹à¥‹à¤‚ +तिनà¥à¤¹à¥‡à¤‚ +तिनà¥à¤¹à¥‹à¤‚ +किनà¥à¤¹à¥‹à¤‚ +किनà¥à¤¹à¥‡à¤‚ +इतà¥à¤¯à¤¾à¤¦à¤¿ +दà¥à¤µà¤¾à¤°à¤¾ +इनà¥à¤¹à¥‡à¤‚ +इनà¥à¤¹à¥‹à¤‚ +उनà¥à¤¹à¥‹à¤‚ +बिलकà¥à¤² +निहायत +ऱà¥à¤µà¤¾à¤¸à¤¾ +इनà¥à¤¹à¥€à¤‚ +उनà¥à¤¹à¥€à¤‚ +उनà¥à¤¹à¥‡à¤‚ +इसमें +जितना +दà¥à¤¸à¤°à¤¾ +कितना +दबारा +साबà¥à¤¤ +वग़ैरह +दूसरे +कौनसा +लेकिन +होता +करने +किया +लिये +अपने +नहीं +दिया +इसका +करना +वाले +सकते +इसके +सबसे +होने +करते +बहà¥à¤¤ +वरà¥à¤— +करें +होती +अपनी +उनके +कहते +होते +करता +उनकी +इसकी +सकता +रखें +अपना +उसके +जिसे +तिसे +किसे +किसी +काफ़ी +पहले +नीचे +बाला +यहाठ+जैसा +जैसे +मानो +अंदर +भीतर +पूरा +सारा +होना +उनको +वहाठ+वहीं +जहाठ+जीधर +उनका +इनका +के +हैं +गया +बनी +à¤à¤µà¤‚ +हà¥à¤† +साथ +बाद +लिठ+कà¥à¤› +कहा +यदि +हà¥à¤ˆ +इसे +हà¥à¤ +अभी +सभी +कà¥à¤² +रहा +रहे +इसी +उसे +जिस +जिन +तिस +तिन +कौन +किस +कोई +à¤à¤¸à¥‡ +तरह +किर +साभ +संग +यही +बही +उसी +फिर +मगर +का +à¤à¤• +यह +से +को +इस +कि +जो +कर +मे +ने +तो +ही +या +हो +था +तक +आप +ये +थे +दो +वे +थी +जा +ना +उस +à¤à¤¸ +पे +उन +सो +भी +और +घर +तब +जब +अत +व न \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_hr.txt b/yake/core/StopwordsList/stopwords_hr.txt similarity index 83% rename from yake/StopwordsList/stopwords_hr.txt rename to yake/core/StopwordsList/stopwords_hr.txt index d049a460..26e4fd91 100644 --- a/yake/StopwordsList/stopwords_hr.txt +++ b/yake/core/StopwordsList/stopwords_hr.txt @@ -1,179 +1,179 @@ -a -ako -ali -bi -bih -bila -bili -bilo -bio -bismo -biste -biti -bumo -da -do -duž -ga -hoće -hoćemo -hoćete -hoćeÅ¡ -hoću -i -iako -ih -ili -iz -ja -je -jedna -jedne -jedno -jer -jesam -jesi -jesmo -jest -jeste -jesu -jim -joj -joÅ¡ -ju -kada -kako -kao -koja -koje -koji -kojima -koju -kroz -li -me -mene -meni -mi -mimo -moj -moja -moje -mu -na -nad -nakon -nam -nama -nas -naÅ¡ -naÅ¡a -naÅ¡e -naÅ¡eg -ne -nego -neka -neki -nekog -neku -nema -netko -neće -nećemo -nećete -nećeÅ¡ -neću -neÅ¡to -ni -nije -nikoga -nikoje -nikoju -nisam -nisi -nismo -niste -nisu -njega -njegov -njegova -njegovo -njemu -njezin -njezina -njezino -njih -njihov -njihova -njihovo -njim -njima -njoj -nju -no -o -od -odmah -on -ona -oni -ono -ova -pa -pak -po -pod -pored -prije -s -sa -sam -samo -se -sebe -sebi -si -smo -ste -su -sve -svi -svog -svoj -svoja -svoje -svom -ta -tada -taj -tako -te -tebe -tebi -ti -to -toj -tome -tu -tvoj -tvoja -tvoje -u -uz -vam -vama -vas -vaÅ¡ -vaÅ¡a -vaÅ¡e -već -vi -vrlo -za -zar -će -ćemo -ćete -ćeÅ¡ -ću +a +ako +ali +bi +bih +bila +bili +bilo +bio +bismo +biste +biti +bumo +da +do +duž +ga +hoće +hoćemo +hoćete +hoćeÅ¡ +hoću +i +iako +ih +ili +iz +ja +je +jedna +jedne +jedno +jer +jesam +jesi +jesmo +jest +jeste +jesu +jim +joj +joÅ¡ +ju +kada +kako +kao +koja +koje +koji +kojima +koju +kroz +li +me +mene +meni +mi +mimo +moj +moja +moje +mu +na +nad +nakon +nam +nama +nas +naÅ¡ +naÅ¡a +naÅ¡e +naÅ¡eg +ne +nego +neka +neki +nekog +neku +nema +netko +neće +nećemo +nećete +nećeÅ¡ +neću +neÅ¡to +ni +nije +nikoga +nikoje +nikoju +nisam +nisi +nismo +niste +nisu +njega +njegov +njegova +njegovo +njemu +njezin +njezina +njezino +njih +njihov +njihova +njihovo +njim +njima +njoj +nju +no +o +od +odmah +on +ona +oni +ono +ova +pa +pak +po +pod +pored +prije +s +sa +sam +samo +se +sebe +sebi +si +smo +ste +su +sve +svi +svog +svoj +svoja +svoje +svom +ta +tada +taj +tako +te +tebe +tebi +ti +to +toj +tome +tu +tvoj +tvoja +tvoje +u +uz +vam +vama +vas +vaÅ¡ +vaÅ¡a +vaÅ¡e +već +vi +vrlo +za +zar +će +ćemo +ćete +ćeÅ¡ +ću Å¡to \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_hu.txt b/yake/core/StopwordsList/stopwords_hu.txt similarity index 90% rename from yake/StopwordsList/stopwords_hu.txt rename to yake/core/StopwordsList/stopwords_hu.txt index dbc6942f..6d911268 100644 --- a/yake/StopwordsList/stopwords_hu.txt +++ b/yake/core/StopwordsList/stopwords_hu.txt @@ -1,737 +1,737 @@ -a -abba -abban -abból -addig -ahhoz -ahol -akár -aki -akik -akkor -alá -alád -alájuk -alám -alánk -alapján -alátok -alatt -alatta -alattad -alattam -alattatok -alattuk -alattunk -alól -alóla -alólad -alólam -alólatok -alóluk -alólunk -által -általában -ám -amely -amelybol -amelyek -amelyekben -amelyeket -amelyet -amelyik -amelynek -ami -amíg -amikor -amit -amott -annak -annál -arra -arról -át -attól -az -azért -aznap -azok -azokat -azokba -azokban -azokból -azokért -azokhoz -azokig -azokká -azokkal -azoknak -azoknál -azokon -azokra -azokról -azoktól -azon -azonban -azonnal -azt -aztán -azzá -azzal -bal -balra -ban -bár -bárcsak -bármilyen -be -belé -beléd -beléjük -belém -belénk -belétek -belÅ‘le -belÅ‘led -belÅ‘lem -belÅ‘letek -belÅ‘lük -belÅ‘lünk -belül -ben -benne -benned -bennem -bennetek -bennük -bennünk -búcsú -csak -csakhogy -csupán -de -dehogy -ebbe -ebben -ebbÅ‘l -eddig -egész -egészen -egy -egyéb -egyebek -egyebet -egyedül -egyelÅ‘re -egyet -egyik -egymás -egyre -egyszerre -együtt -ehhez -el -elé -eléd -elég -eleinte -eléjük -elém -elénk -elétek -éljen -ellen -ellenére -ellenes -elleni -elmondta -elÅ‘bb -elÅ‘l -elÅ‘le -elÅ‘led -elÅ‘lem -elÅ‘letek -elÅ‘lük -elÅ‘lünk -elÅ‘ször -elÅ‘tt -elÅ‘tte -elÅ‘tted -elÅ‘ttem -elÅ‘ttetek -elÅ‘ttük -elÅ‘ttünk -elÅ‘zÅ‘ -elsÅ‘ -elsÅ‘k -elsÅ‘sorban -elsÅ‘t -én -engem -ennek -ennél -ennyi -enyém -erre -errÅ‘l -érte -érted -értem -értetek -értük -értünk -és -esetben -ettÅ‘l -év -évben -éve -évek -éves -évi -évvel -ez -ezek -ezekbe -ezekben -ezekbÅ‘l -ezeken -ezekért -ezeket -ezekhez -ezekig -ezekké -ezekkel -ezeknek -ezeknél -ezekre -ezekrÅ‘l -ezektÅ‘l -ezen -ezentúl -ezer -ezért -ezret -ezt -ezután -ezzé -ezzel -fel -fél -fele -felé -felek -felet -felett -fent -fenti -fölé -gyakran -ha -halló -hamar -hanem -hány -hányszor -harmadik -harmadikat -hármat -harminc -három -hat -hát -hátha -hatodik -hatodikat -hatot -hátulsó -hatvan -helyett -hét -hetedik -hetediket -hetet -hetven -hiába -hirtelen -hiszen -hogy -hol -holnap -holnapot -honnan -hova -hozzá -hozzád -hozzájuk -hozzám -hozzánk -hozzátok -hurrá -húsz -huszadik -idén -ide-þda -igazán -igen -így -illetve -ilyen -immár -inkább -is -ismét -itt -jelenleg -jó -jobban -jobbra -jól -jólesik -jóval -jövÅ‘re -kell -kellene -kellett -kelljen -képest -kérem -kérlek -késÅ‘ -késÅ‘bb -késÅ‘n -kész -két -kétszer -ketten -kettÅ‘ -kettÅ‘t -kevés -ki -kiben -kibÅ‘l -kicsit -kicsoda -kié -kiért -kihez -kik -kikbe -kikben -kikbÅ‘l -kiken -kikért -kiket -kikhez -kikké -kikkel -kiknek -kiknél -kikre -kikrÅ‘l -kiktÅ‘l -kilenc -kilencedik -kilencediket -kilencet -kilencven -kin -kinek -kinél -kire -kirÅ‘l -kit -kitÅ‘l -kivé -kivel -korábban -körül -köszönhetÅ‘en -köszönöm -közben -közé -közel -közepén -közepesen -között -közül -külön -különben -különbözÅ‘ -különbözÅ‘bb -különbözÅ‘ek -lassan -le -legalább -legyen -lehet -lehetetlen -lehetÅ‘leg -lehetÅ‘ség -lenne -lennék -lennének -lesz -leszek -lesznek -leszünk -lett -lettek -lettem -lettünk -lévÅ‘ -ma -maga -magad -magam -magát -magatokat -magukat -magunkat -mai -majd -majdnem -manapság -már -más -másik -másikat -másnap -második -másodszor -mások -másokat -mást -meg -még -megcsinál -megcsinálnak -megint -mégis -megvan -mellé -melléd -melléjük -mellém -mellénk -mellétek -mellett -mellette -melletted -mellettem -mellettetek -mellettük -mellettünk -mellÅ‘l -mellÅ‘le -mellÅ‘led -mellÅ‘lem -mellÅ‘letek -mellÅ‘lük -mellÅ‘lünk -melyik -mennyi -mert -mi -miatt -miatta -miattad -miattam -miattatok -miattuk -miattunk -mibe -miben -mibÅ‘l -miért -míg -mihez -mik -mikbe -mikben -mikbÅ‘l -miken -mikért -miket -mikhez -mikké -mikkel -miknek -miknél -mikor -mikre -mikrÅ‘l -miktÅ‘l -milyen -min -mind -mindegyik -mindegyiket -minden -mindenesetre -mindenki -mindent -mindenütt -mindig -mindketten -minek -minél -minket -mint -mire -mirÅ‘l -mit -mitÅ‘l -mivé -mivel -mögé -mögéd -mögéjük -mögém -mögénk -mögétek -mögött -mögötte -mögötted -mögöttem -mögöttetek -mögöttük -mögöttünk -mögül -mögüle -mögüled -mögülem -mögületek -mögülük -mögülünk -mondta -most -mostanáig -múltkor -múlva -na -nagyon -nála -nálad -nálam -nálatok -náluk -nálunk -naponta -napot -ne -négy -negyedik -negyediket -négyet -negyven -néha -néhány -neked -nekem -neki -nekik -nektek -nekünk -nélkül -nem -nemcsak -nemrég -nincs -nyolc -nyolcadik -nyolcadikat -nyolcat -nyolcvan -Å‘ -Å‘k -Å‘ket -olyan -ön -önbe -önben -önbÅ‘l -önért -önhöz -onnan -önnek -önnel -önnél -önök -önökbe -önökben -önökbÅ‘l -önökért -önöket -önökhöz -önökkel -önöknek -önöknél -önökön -önökre -önökrÅ‘l -önöktÅ‘l -önön -önre -önrÅ‘l -önt -öntÅ‘l -öt -Å‘t -óta -ötödik -ötödiket -ötöt -ott -ötven -pár -pedig -például -persze -rá -rád -rajta -rajtad -rajtam -rajtatok -rajtuk -rajtunk -rájuk -rám -ránk -rátok -régen -régóta -rendben -részére -rögtön -róla -rólad -rólam -rólatok -róluk -rólunk -rosszul -se -sem -semmi -semmilyen -semmiség -senki -soha -sok -sokáig -sokan -sokszor -során -sÅ‘t -stb. -számára -száz -századik -százat -szemben -szépen -szerbusz -szerint -szerinte -szerinted -szerintem -szerintetek -szerintük -szerintünk -szervusz -szinte -szíves -szívesen -szíveskedjék -talán -tavaly -távol -te -téged -tegnap -tegnapelÅ‘tt -tehát -tele -tényleg -tessék -ti -tied -titeket -tíz -tizedik -tizediket -tizenegy -tizenegyedik -tizenhárom -tizenhat -tizenhét -tizenkét -tizenkettedik -tizenkettÅ‘ -tizenkilenc -tizennégy -tizennyolc -tizenöt -tizet -több -többi -többször -tÅ‘le -tÅ‘led -tÅ‘lem -tÅ‘letek -tÅ‘lük -tÅ‘lünk -tovább -további -túl -úgy -ugyanakkor -ugyanez -ugyanis -ugye -úgyis -úgynevezett -újra -úr -urak -uram -urat -után -utoljára -utolsó -vagy -vagyis -vagyok -vagytok -vagyunk -vajon -valahol -valaki -valakit -valamelyik -valami -valamint -van -vannak -végén -végre -végül -vele -veled -velem -veletek -velük -velünk -viszlát -viszont -viszontlátásra -volna -volnának -volnék -volt -voltak -voltam +a +abba +abban +abból +addig +ahhoz +ahol +akár +aki +akik +akkor +alá +alád +alájuk +alám +alánk +alapján +alátok +alatt +alatta +alattad +alattam +alattatok +alattuk +alattunk +alól +alóla +alólad +alólam +alólatok +alóluk +alólunk +által +általában +ám +amely +amelybol +amelyek +amelyekben +amelyeket +amelyet +amelyik +amelynek +ami +amíg +amikor +amit +amott +annak +annál +arra +arról +át +attól +az +azért +aznap +azok +azokat +azokba +azokban +azokból +azokért +azokhoz +azokig +azokká +azokkal +azoknak +azoknál +azokon +azokra +azokról +azoktól +azon +azonban +azonnal +azt +aztán +azzá +azzal +bal +balra +ban +bár +bárcsak +bármilyen +be +belé +beléd +beléjük +belém +belénk +belétek +belÅ‘le +belÅ‘led +belÅ‘lem +belÅ‘letek +belÅ‘lük +belÅ‘lünk +belül +ben +benne +benned +bennem +bennetek +bennük +bennünk +búcsú +csak +csakhogy +csupán +de +dehogy +ebbe +ebben +ebbÅ‘l +eddig +egész +egészen +egy +egyéb +egyebek +egyebet +egyedül +egyelÅ‘re +egyet +egyik +egymás +egyre +egyszerre +együtt +ehhez +el +elé +eléd +elég +eleinte +eléjük +elém +elénk +elétek +éljen +ellen +ellenére +ellenes +elleni +elmondta +elÅ‘bb +elÅ‘l +elÅ‘le +elÅ‘led +elÅ‘lem +elÅ‘letek +elÅ‘lük +elÅ‘lünk +elÅ‘ször +elÅ‘tt +elÅ‘tte +elÅ‘tted +elÅ‘ttem +elÅ‘ttetek +elÅ‘ttük +elÅ‘ttünk +elÅ‘zÅ‘ +elsÅ‘ +elsÅ‘k +elsÅ‘sorban +elsÅ‘t +én +engem +ennek +ennél +ennyi +enyém +erre +errÅ‘l +érte +érted +értem +értetek +értük +értünk +és +esetben +ettÅ‘l +év +évben +éve +évek +éves +évi +évvel +ez +ezek +ezekbe +ezekben +ezekbÅ‘l +ezeken +ezekért +ezeket +ezekhez +ezekig +ezekké +ezekkel +ezeknek +ezeknél +ezekre +ezekrÅ‘l +ezektÅ‘l +ezen +ezentúl +ezer +ezért +ezret +ezt +ezután +ezzé +ezzel +fel +fél +fele +felé +felek +felet +felett +fent +fenti +fölé +gyakran +ha +halló +hamar +hanem +hány +hányszor +harmadik +harmadikat +hármat +harminc +három +hat +hát +hátha +hatodik +hatodikat +hatot +hátulsó +hatvan +helyett +hét +hetedik +hetediket +hetet +hetven +hiába +hirtelen +hiszen +hogy +hol +holnap +holnapot +honnan +hova +hozzá +hozzád +hozzájuk +hozzám +hozzánk +hozzátok +hurrá +húsz +huszadik +idén +ide-þda +igazán +igen +így +illetve +ilyen +immár +inkább +is +ismét +itt +jelenleg +jó +jobban +jobbra +jól +jólesik +jóval +jövÅ‘re +kell +kellene +kellett +kelljen +képest +kérem +kérlek +késÅ‘ +késÅ‘bb +késÅ‘n +kész +két +kétszer +ketten +kettÅ‘ +kettÅ‘t +kevés +ki +kiben +kibÅ‘l +kicsit +kicsoda +kié +kiért +kihez +kik +kikbe +kikben +kikbÅ‘l +kiken +kikért +kiket +kikhez +kikké +kikkel +kiknek +kiknél +kikre +kikrÅ‘l +kiktÅ‘l +kilenc +kilencedik +kilencediket +kilencet +kilencven +kin +kinek +kinél +kire +kirÅ‘l +kit +kitÅ‘l +kivé +kivel +korábban +körül +köszönhetÅ‘en +köszönöm +közben +közé +közel +közepén +közepesen +között +közül +külön +különben +különbözÅ‘ +különbözÅ‘bb +különbözÅ‘ek +lassan +le +legalább +legyen +lehet +lehetetlen +lehetÅ‘leg +lehetÅ‘ség +lenne +lennék +lennének +lesz +leszek +lesznek +leszünk +lett +lettek +lettem +lettünk +lévÅ‘ +ma +maga +magad +magam +magát +magatokat +magukat +magunkat +mai +majd +majdnem +manapság +már +más +másik +másikat +másnap +második +másodszor +mások +másokat +mást +meg +még +megcsinál +megcsinálnak +megint +mégis +megvan +mellé +melléd +melléjük +mellém +mellénk +mellétek +mellett +mellette +melletted +mellettem +mellettetek +mellettük +mellettünk +mellÅ‘l +mellÅ‘le +mellÅ‘led +mellÅ‘lem +mellÅ‘letek +mellÅ‘lük +mellÅ‘lünk +melyik +mennyi +mert +mi +miatt +miatta +miattad +miattam +miattatok +miattuk +miattunk +mibe +miben +mibÅ‘l +miért +míg +mihez +mik +mikbe +mikben +mikbÅ‘l +miken +mikért +miket +mikhez +mikké +mikkel +miknek +miknél +mikor +mikre +mikrÅ‘l +miktÅ‘l +milyen +min +mind +mindegyik +mindegyiket +minden +mindenesetre +mindenki +mindent +mindenütt +mindig +mindketten +minek +minél +minket +mint +mire +mirÅ‘l +mit +mitÅ‘l +mivé +mivel +mögé +mögéd +mögéjük +mögém +mögénk +mögétek +mögött +mögötte +mögötted +mögöttem +mögöttetek +mögöttük +mögöttünk +mögül +mögüle +mögüled +mögülem +mögületek +mögülük +mögülünk +mondta +most +mostanáig +múltkor +múlva +na +nagyon +nála +nálad +nálam +nálatok +náluk +nálunk +naponta +napot +ne +négy +negyedik +negyediket +négyet +negyven +néha +néhány +neked +nekem +neki +nekik +nektek +nekünk +nélkül +nem +nemcsak +nemrég +nincs +nyolc +nyolcadik +nyolcadikat +nyolcat +nyolcvan +Å‘ +Å‘k +Å‘ket +olyan +ön +önbe +önben +önbÅ‘l +önért +önhöz +onnan +önnek +önnel +önnél +önök +önökbe +önökben +önökbÅ‘l +önökért +önöket +önökhöz +önökkel +önöknek +önöknél +önökön +önökre +önökrÅ‘l +önöktÅ‘l +önön +önre +önrÅ‘l +önt +öntÅ‘l +öt +Å‘t +óta +ötödik +ötödiket +ötöt +ott +ötven +pár +pedig +például +persze +rá +rád +rajta +rajtad +rajtam +rajtatok +rajtuk +rajtunk +rájuk +rám +ránk +rátok +régen +régóta +rendben +részére +rögtön +róla +rólad +rólam +rólatok +róluk +rólunk +rosszul +se +sem +semmi +semmilyen +semmiség +senki +soha +sok +sokáig +sokan +sokszor +során +sÅ‘t +stb. +számára +száz +századik +százat +szemben +szépen +szerbusz +szerint +szerinte +szerinted +szerintem +szerintetek +szerintük +szerintünk +szervusz +szinte +szíves +szívesen +szíveskedjék +talán +tavaly +távol +te +téged +tegnap +tegnapelÅ‘tt +tehát +tele +tényleg +tessék +ti +tied +titeket +tíz +tizedik +tizediket +tizenegy +tizenegyedik +tizenhárom +tizenhat +tizenhét +tizenkét +tizenkettedik +tizenkettÅ‘ +tizenkilenc +tizennégy +tizennyolc +tizenöt +tizet +több +többi +többször +tÅ‘le +tÅ‘led +tÅ‘lem +tÅ‘letek +tÅ‘lük +tÅ‘lünk +tovább +további +túl +úgy +ugyanakkor +ugyanez +ugyanis +ugye +úgyis +úgynevezett +újra +úr +urak +uram +urat +után +utoljára +utolsó +vagy +vagyis +vagyok +vagytok +vagyunk +vajon +valahol +valaki +valakit +valamelyik +valami +valamint +van +vannak +végén +végre +végül +vele +veled +velem +veletek +velük +velünk +viszlát +viszont +viszontlátásra +volna +volnának +volnék +volt +voltak +voltam voltunk \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_hy.txt b/yake/core/StopwordsList/stopwords_hy.txt similarity index 87% rename from yake/StopwordsList/stopwords_hy.txt rename to yake/core/StopwordsList/stopwords_hy.txt index 10a5b8f7..327af43d 100644 --- a/yake/StopwordsList/stopwords_hy.txt +++ b/yake/core/StopwordsList/stopwords_hy.txt @@ -1,45 +1,45 @@ -Õ¡ÕµÕ¤ -Õ¡ÕµÕ¬ -Õ¡ÕµÕ¶ -Õ¡ÕµÕ½ -Õ¤Õ¸Ö‚ -Õ¤Õ¸Ö‚Ö„ -Õ¥Õ´ -Õ¥Õ¶ -Õ¥Õ¶Ö„ -Õ¥Õ½ -Õ¥Ö„ -Õ§ -Õ§Õ« -Õ§Õ«Õ¶ -Õ§Õ«Õ¶Ö„ -Õ§Õ«Ö€ -Õ§Õ«Ö„ -Õ§Ö€ -Õ¨Õ½Õ¿ -Õ© -Õ« -Õ«Õ¶ -Õ«Õ½Õ¯ -Õ«Ö€ -Õ¯Õ¡Õ´ -Õ°Õ¡Õ´Õ¡Ö€ -Õ°Õ¥Õ¿ -Õ°Õ¥Õ¿Õ¸ -Õ´Õ¥Õ¶Ö„ -Õ´Õ¥Õ» -Õ´Õ« -Õ¶ -Õ¶Õ¡ -Õ¶Õ¡Ö‡ -Õ¶Ö€Õ¡ -Õ¶Ö€Õ¡Õ¶Ö„ -Õ¸Ö€ -Õ¸Ö€Õ¨ -Õ¸Ö€Õ¸Õ¶Ö„ -Õ¸Ö€ÕºÕ¥Õ½ -Õ¸Ö‚ -Õ¸Ö‚Õ´ -ÕºÕ«Õ¿Õ« -Õ¾Ö€Õ¡ +Õ¡ÕµÕ¤ +Õ¡ÕµÕ¬ +Õ¡ÕµÕ¶ +Õ¡ÕµÕ½ +Õ¤Õ¸Ö‚ +Õ¤Õ¸Ö‚Ö„ +Õ¥Õ´ +Õ¥Õ¶ +Õ¥Õ¶Ö„ +Õ¥Õ½ +Õ¥Ö„ +Õ§ +Õ§Õ« +Õ§Õ«Õ¶ +Õ§Õ«Õ¶Ö„ +Õ§Õ«Ö€ +Õ§Õ«Ö„ +Õ§Ö€ +Õ¨Õ½Õ¿ +Õ© +Õ« +Õ«Õ¶ +Õ«Õ½Õ¯ +Õ«Ö€ +Õ¯Õ¡Õ´ +Õ°Õ¡Õ´Õ¡Ö€ +Õ°Õ¥Õ¿ +Õ°Õ¥Õ¿Õ¸ +Õ´Õ¥Õ¶Ö„ +Õ´Õ¥Õ» +Õ´Õ« +Õ¶ +Õ¶Õ¡ +Õ¶Õ¡Ö‡ +Õ¶Ö€Õ¡ +Õ¶Ö€Õ¡Õ¶Ö„ +Õ¸Ö€ +Õ¸Ö€Õ¨ +Õ¸Ö€Õ¸Õ¶Ö„ +Õ¸Ö€ÕºÕ¥Õ½ +Õ¸Ö‚ +Õ¸Ö‚Õ´ +ÕºÕ«Õ¿Õ« +Õ¾Ö€Õ¡ Ö‡ \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_id.txt b/yake/core/StopwordsList/stopwords_id.txt similarity index 88% rename from yake/StopwordsList/stopwords_id.txt rename to yake/core/StopwordsList/stopwords_id.txt index fbf611fb..7f876e57 100644 --- a/yake/StopwordsList/stopwords_id.txt +++ b/yake/core/StopwordsList/stopwords_id.txt @@ -1,359 +1,359 @@ -# from appendix D of: A Study of Stemming Effects on Information -# Retrieval in Bahasa Indonesia -ada -adanya -adalah -adapun -agak -agaknya -agar -akan -akankah -akhirnya -aku -akulah -amat -amatlah -anda -andalah -antar -diantaranya -antara -antaranya -diantara -apa -apaan -mengapa -apabila -apakah -apalagi -apatah -atau -ataukah -ataupun -bagai -bagaikan -sebagai -sebagainya -bagaimana -bagaimanapun -sebagaimana -bagaimanakah -bagi -bahkan -bahwa -bahwasanya -sebaliknya -banyak -sebanyak -beberapa -seberapa -begini -beginian -beginikah -beginilah -sebegini -begitu -begitukah -begitulah -begitupun -sebegitu -belum -belumlah -sebelum -sebelumnya -sebenarnya -berapa -berapakah -berapalah -berapapun -betulkah -sebetulnya -biasa -biasanya -bila -bilakah -bisa -bisakah -sebisanya -boleh -bolehkah -bolehlah -buat -bukan -bukankah -bukanlah -bukannya -cuma -percuma -dahulu -dalam -dan -dapat -dari -daripada -dekat -demi -demikian -demikianlah -sedemikian -dengan -depan -di -dia -dialah -dini -diri -dirinya -terdiri -dong -dulu -enggak -enggaknya -entah -entahlah -terhadap -terhadapnya -hal -hampir -hanya -hanyalah -harus -haruslah -harusnya -seharusnya -hendak -hendaklah -hendaknya -hingga -sehingga -ia -ialah -ibarat -ingin -inginkah -inginkan -ini -inikah -inilah -itu -itukah -itulah -jangan -jangankan -janganlah -jika -jikalau -juga -justru -kala -kalau -kalaulah -kalaupun -kalian -kami -kamilah -kamu -kamulah -kan -kapan -kapankah -kapanpun -dikarenakan -karena -karenanya -ke -kecil -kemudian -kenapa -kepada -kepadanya -ketika -seketika -khususnya -kini -kinilah -kiranya -sekiranya -kita -kitalah -kok -lagi -lagian -selagi -lah -lain -lainnya -melainkan -selaku -lalu -melalui -terlalu -lama -lamanya -selama -selama -selamanya -lebih -terlebih -bermacam -macam -semacam -maka -makanya -makin -malah -malahan -mampu -mampukah -mana -manakala -manalagi -masih -masihkah -semasih -masing -mau -maupun -semaunya -memang -mereka -merekalah -meski -meskipun -semula -mungkin -mungkinkah -nah -namun -nanti -nantinya -nyaris -oleh -olehnya -seorang -seseorang -pada -padanya -padahal -paling -sepanjang -pantas -sepantasnya -sepantasnyalah -para -pasti -pastilah -per -pernah -pula -pun -merupakan -rupanya -serupa -saat -saatnya -sesaat -saja -sajalah -saling -bersama -sama -sesama -sambil -sampai -sana -sangat -sangatlah -saya -sayalah -se -sebab -sebabnya -sebuah -tersebut -tersebutlah -sedang -sedangkan -sedikit -sedikitnya -segala -segalanya -segera -sesegera -sejak -sejenak -sekali -sekalian -sekalipun -sesekali -sekaligus -sekarang -sekarang -sekitar -sekitarnya -sela -selain -selalu -seluruh -seluruhnya -semakin -sementara -sempat -semua -semuanya -sendiri -sendirinya -seolah -seperti -sepertinya -sering -seringnya -serta -siapa -siapakah -siapapun -disini -disinilah -sini -sinilah -sesuatu -sesuatunya -suatu -sesudah -sesudahnya -sudah -sudahkah -sudahlah -supaya -tadi -tadinya -tak -tanpa -setelah -telah -tentang -tentu -tentulah -tentunya -tertentu -seterusnya -tapi -tetapi -setiap -tiap -setidaknya -tidak -tidakkah -tidaklah -toh -waduh -wah -wahai -sewaktu -walau -walaupun -wong -yaitu -yakni +# from appendix D of: A Study of Stemming Effects on Information +# Retrieval in Bahasa Indonesia +ada +adanya +adalah +adapun +agak +agaknya +agar +akan +akankah +akhirnya +aku +akulah +amat +amatlah +anda +andalah +antar +diantaranya +antara +antaranya +diantara +apa +apaan +mengapa +apabila +apakah +apalagi +apatah +atau +ataukah +ataupun +bagai +bagaikan +sebagai +sebagainya +bagaimana +bagaimanapun +sebagaimana +bagaimanakah +bagi +bahkan +bahwa +bahwasanya +sebaliknya +banyak +sebanyak +beberapa +seberapa +begini +beginian +beginikah +beginilah +sebegini +begitu +begitukah +begitulah +begitupun +sebegitu +belum +belumlah +sebelum +sebelumnya +sebenarnya +berapa +berapakah +berapalah +berapapun +betulkah +sebetulnya +biasa +biasanya +bila +bilakah +bisa +bisakah +sebisanya +boleh +bolehkah +bolehlah +buat +bukan +bukankah +bukanlah +bukannya +cuma +percuma +dahulu +dalam +dan +dapat +dari +daripada +dekat +demi +demikian +demikianlah +sedemikian +dengan +depan +di +dia +dialah +dini +diri +dirinya +terdiri +dong +dulu +enggak +enggaknya +entah +entahlah +terhadap +terhadapnya +hal +hampir +hanya +hanyalah +harus +haruslah +harusnya +seharusnya +hendak +hendaklah +hendaknya +hingga +sehingga +ia +ialah +ibarat +ingin +inginkah +inginkan +ini +inikah +inilah +itu +itukah +itulah +jangan +jangankan +janganlah +jika +jikalau +juga +justru +kala +kalau +kalaulah +kalaupun +kalian +kami +kamilah +kamu +kamulah +kan +kapan +kapankah +kapanpun +dikarenakan +karena +karenanya +ke +kecil +kemudian +kenapa +kepada +kepadanya +ketika +seketika +khususnya +kini +kinilah +kiranya +sekiranya +kita +kitalah +kok +lagi +lagian +selagi +lah +lain +lainnya +melainkan +selaku +lalu +melalui +terlalu +lama +lamanya +selama +selama +selamanya +lebih +terlebih +bermacam +macam +semacam +maka +makanya +makin +malah +malahan +mampu +mampukah +mana +manakala +manalagi +masih +masihkah +semasih +masing +mau +maupun +semaunya +memang +mereka +merekalah +meski +meskipun +semula +mungkin +mungkinkah +nah +namun +nanti +nantinya +nyaris +oleh +olehnya +seorang +seseorang +pada +padanya +padahal +paling +sepanjang +pantas +sepantasnya +sepantasnyalah +para +pasti +pastilah +per +pernah +pula +pun +merupakan +rupanya +serupa +saat +saatnya +sesaat +saja +sajalah +saling +bersama +sama +sesama +sambil +sampai +sana +sangat +sangatlah +saya +sayalah +se +sebab +sebabnya +sebuah +tersebut +tersebutlah +sedang +sedangkan +sedikit +sedikitnya +segala +segalanya +segera +sesegera +sejak +sejenak +sekali +sekalian +sekalipun +sesekali +sekaligus +sekarang +sekarang +sekitar +sekitarnya +sela +selain +selalu +seluruh +seluruhnya +semakin +sementara +sempat +semua +semuanya +sendiri +sendirinya +seolah +seperti +sepertinya +sering +seringnya +serta +siapa +siapakah +siapapun +disini +disinilah +sini +sinilah +sesuatu +sesuatunya +suatu +sesudah +sesudahnya +sudah +sudahkah +sudahlah +supaya +tadi +tadinya +tak +tanpa +setelah +telah +tentang +tentu +tentulah +tentunya +tertentu +seterusnya +tapi +tetapi +setiap +tiap +setidaknya +tidak +tidakkah +tidaklah +toh +waduh +wah +wahai +sewaktu +walau +walaupun +wong +yaitu +yakni yang \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_it.txt b/yake/core/StopwordsList/stopwords_it.txt similarity index 85% rename from yake/StopwordsList/stopwords_it.txt rename to yake/core/StopwordsList/stopwords_it.txt index 4e0a50d3..9dc97512 100644 --- a/yake/StopwordsList/stopwords_it.txt +++ b/yake/core/StopwordsList/stopwords_it.txt @@ -1,398 +1,398 @@ -a -abbastanza -accidenti -ad -adesso -affinche -agli -ahime -ahimè -ai -al -alcuna -alcuni -alcuno -all -alla -alle -allo -altri -altrimenti -altro -altrui -anche -ancora -anni -anno -ansa -assai -attesa -avanti -avendo -avente -aver -avere -avete -aveva -avuta -avute -avuti -avuto -basta -bene -benissimo -berlusconi -brava -bravo -c -casa -caso -cento -certa -certe -certi -certo -che -chi -chicchessia -chiunque -ci -ciascuna -ciascuno -cima -cio -ciò -cioe -cioè -circa -citta -città -codesta -codesti -codesto -cogli -coi -col -colei -coll -coloro -colui -come -con -concernente -consiglio -contro -cortesia -cos -cosa -cosi -così -cui -d -da -dagli -dai -dal -dall -dalla -dalle -dallo -davanti -degli -dei -del -dell -della -delle -dello -dentro -detto -deve -di -dice -dietro -dire -dirimpetto -dopo -dove -dovra -dovrà -due -dunque -durante -e -è -ecco -ed -egli -ella -eppure -era -erano -esse -essendo -esser -essere -essi -ex -fa -fare -fatto -favore -fin -finalmente -finche -fine -fino -forse -fra -fuori -gia -già -giacche -giorni -giorno -gli -gliela -gliele -glieli -glielo -gliene -governo -grande -grazie -gruppo -ha -hai -hanno -ho -i -ieri -il -improvviso -in -infatti -insieme -intanto -intorno -invece -io -l -la -là -lavoro -le -lei -li -lo -lontano -loro -lui -lungo -ma -macche -magari -mai -male -malgrado -malissimo -me -medesimo -mediante -meglio -meno -mentre -mesi -mezzo -mi -mia -mie -miei -mila -miliardi -milioni -mio -moltissimo -molto -mondo -nazionale -ne -negli -nei -nel -nell -nella -nelle -nello -nemmeno -neppure -nessuna -nessuno -niente -no -noi -non -nondimeno -nostra -nostre -nostri -nostro -nulla -nuovo -o -od -oggi -ogni -ognuna -ognuno -oltre -oppure -ora -ore -osi -ossia -paese -parecchi -parecchie -parecchio -parte -partendo -peccato -peggio -per -perche -perchè -percio -perciò -perfino -pero -però -persone -piedi -pieno -piglia -piu -più -po -pochissimo -poco -poi -poiche -press -prima -primo -proprio -puo -può -pure -purtroppo -qualche -qualcuna -qualcuno -quale -quali -qualunque -quando -quanta -quante -quanti -quanto -quantunque -quasi -quattro -quel -quella -quelli -quello -quest -questa -queste -questi -questo -qui -quindi -riecco -salvo -sara -sarà -sarebbe -scopo -scorso -se -secondo -seguente -sei -sempre -senza -si -sia -siamo -siete -solito -solo -sono -sopra -sotto -sta -staranno -stata -state -stati -stato -stesso -su -sua -successivo -sue -sugli -sui -sul -sull -sulla -sulle -sullo -suo -suoi -tale -talvolta -tanto -te -tempo -ti -torino -tra -tranne -tre -troppo -tu -tua -tue -tuo -tuoi -tutta -tuttavia -tutte -tutti -tutto -uguali -un -una -uno -uomo -va -vale -varia -varie -vario -verso -vi -via -vicino -visto -vita -voi -volta -vostra -vostre -vostri +a +abbastanza +accidenti +ad +adesso +affinche +agli +ahime +ahimè +ai +al +alcuna +alcuni +alcuno +all +alla +alle +allo +altri +altrimenti +altro +altrui +anche +ancora +anni +anno +ansa +assai +attesa +avanti +avendo +avente +aver +avere +avete +aveva +avuta +avute +avuti +avuto +basta +bene +benissimo +berlusconi +brava +bravo +c +casa +caso +cento +certa +certe +certi +certo +che +chi +chicchessia +chiunque +ci +ciascuna +ciascuno +cima +cio +ciò +cioe +cioè +circa +citta +città +codesta +codesti +codesto +cogli +coi +col +colei +coll +coloro +colui +come +con +concernente +consiglio +contro +cortesia +cos +cosa +cosi +così +cui +d +da +dagli +dai +dal +dall +dalla +dalle +dallo +davanti +degli +dei +del +dell +della +delle +dello +dentro +detto +deve +di +dice +dietro +dire +dirimpetto +dopo +dove +dovra +dovrà +due +dunque +durante +e +è +ecco +ed +egli +ella +eppure +era +erano +esse +essendo +esser +essere +essi +ex +fa +fare +fatto +favore +fin +finalmente +finche +fine +fino +forse +fra +fuori +gia +già +giacche +giorni +giorno +gli +gliela +gliele +glieli +glielo +gliene +governo +grande +grazie +gruppo +ha +hai +hanno +ho +i +ieri +il +improvviso +in +infatti +insieme +intanto +intorno +invece +io +l +la +là +lavoro +le +lei +li +lo +lontano +loro +lui +lungo +ma +macche +magari +mai +male +malgrado +malissimo +me +medesimo +mediante +meglio +meno +mentre +mesi +mezzo +mi +mia +mie +miei +mila +miliardi +milioni +mio +moltissimo +molto +mondo +nazionale +ne +negli +nei +nel +nell +nella +nelle +nello +nemmeno +neppure +nessuna +nessuno +niente +no +noi +non +nondimeno +nostra +nostre +nostri +nostro +nulla +nuovo +o +od +oggi +ogni +ognuna +ognuno +oltre +oppure +ora +ore +osi +ossia +paese +parecchi +parecchie +parecchio +parte +partendo +peccato +peggio +per +perche +perchè +percio +perciò +perfino +pero +però +persone +piedi +pieno +piglia +piu +più +po +pochissimo +poco +poi +poiche +press +prima +primo +proprio +puo +può +pure +purtroppo +qualche +qualcuna +qualcuno +quale +quali +qualunque +quando +quanta +quante +quanti +quanto +quantunque +quasi +quattro +quel +quella +quelli +quello +quest +questa +queste +questi +questo +qui +quindi +riecco +salvo +sara +sarà +sarebbe +scopo +scorso +se +secondo +seguente +sei +sempre +senza +si +sia +siamo +siete +solito +solo +sono +sopra +sotto +sta +staranno +stata +state +stati +stato +stesso +su +sua +successivo +sue +sugli +sui +sul +sull +sulla +sulle +sullo +suo +suoi +tale +talvolta +tanto +te +tempo +ti +torino +tra +tranne +tre +troppo +tu +tua +tue +tuo +tuoi +tutta +tuttavia +tutte +tutti +tutto +uguali +un +una +uno +uomo +va +vale +varia +varie +vario +verso +vi +via +vicino +visto +vita +voi +volta +vostra +vostre +vostri vostro \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_ja.txt b/yake/core/StopwordsList/stopwords_ja.txt similarity index 87% rename from yake/StopwordsList/stopwords_ja.txt rename to yake/core/StopwordsList/stopwords_ja.txt index c57e8f3a..1f6462e1 100644 --- a/yake/StopwordsList/stopwords_ja.txt +++ b/yake/core/StopwordsList/stopwords_ja.txt @@ -1,44 +1,44 @@ -ã“れ -ãれ -ã‚れ -ã“ã® -ãã® -ã‚ã® -ã“ã“ -ãã“ -ã‚ãã“ -ã“ã¡ã‚‰ -ã©ã“ -ã ã‚Œ -ãªã« -ãªã‚“ -何 -ç§ -è²´æ–¹ -貴方方 -我々 -ç§é” -ã‚ã®äºº -ã‚ã®ã‹ãŸ -彼女 -å½¼ -ã§ã™ -ã‚りã¾ã™ -ãŠã‚Šã¾ã™ -ã„ã¾ã™ -㯠-㌠-ã® -ã« -ã‚’ -ã§ -㈠-ã‹ã‚‰ -ã¾ã§ -より -ã‚‚ -ã©ã® -㨠-ã— -ãれ㧠+ã“れ +ãれ +ã‚れ +ã“ã® +ãã® +ã‚ã® +ã“ã“ +ãã“ +ã‚ãã“ +ã“ã¡ã‚‰ +ã©ã“ +ã ã‚Œ +ãªã« +ãªã‚“ +何 +ç§ +è²´æ–¹ +貴方方 +我々 +ç§é” +ã‚ã®äºº +ã‚ã®ã‹ãŸ +彼女 +å½¼ +ã§ã™ +ã‚りã¾ã™ +ãŠã‚Šã¾ã™ +ã„ã¾ã™ +㯠+㌠+ã® +ã« +ã‚’ +ã§ +㈠+ã‹ã‚‰ +ã¾ã§ +より +ã‚‚ +ã©ã® +㨠+ã— +ãれ㧠ã—ã‹ã— \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_lt.txt b/yake/core/StopwordsList/stopwords_lt.txt similarity index 85% rename from yake/StopwordsList/stopwords_lt.txt rename to yake/core/StopwordsList/stopwords_lt.txt index d282c514..0e98aad7 100644 --- a/yake/StopwordsList/stopwords_lt.txt +++ b/yake/core/StopwordsList/stopwords_lt.txt @@ -1,65 +1,65 @@ -apie -po -pireð -visi -taip pat -yra -nëra -klausimas -klausti -tarp -bet -gali -negali -kiekvienas -nei -net -kiekvienas -ieðkoti -nuo -gauti -gauna -turëjo -turi -jo -jos -èia -jam -kaip -á -að -tik -maþiau -daryti -daug -maþai -daugiau -daugiausia -turi -ðalia -niekada -niekas -dabar -daþnai -kartà -vienas -tik -kitas -mûsø -per -praðau -tikrai -pasakë -sakë -sakyti -maþas -kada -negu -aèiû -tas -iki -kas -kam -taip -ne +apie +po +pireð +visi +taip pat +yra +nëra +klausimas +klausti +tarp +bet +gali +negali +kiekvienas +nei +net +kiekvienas +ieðkoti +nuo +gauti +gauna +turëjo +turi +jo +jos +èia +jam +kaip +á +að +tik +maþiau +daryti +daug +maþai +daugiau +daugiausia +turi +ðalia +niekada +niekas +dabar +daþnai +kartà +vienas +tik +kitas +mûsø +per +praðau +tikrai +pasakë +sakë +sakyti +maþas +kada +negu +aèiû +tas +iki +kas +kam +taip +ne tavo \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_lv.txt b/yake/core/StopwordsList/stopwords_lv.txt similarity index 86% rename from yake/StopwordsList/stopwords_lv.txt rename to yake/core/StopwordsList/stopwords_lv.txt index a569f7c6..d536b5c7 100644 --- a/yake/StopwordsList/stopwords_lv.txt +++ b/yake/core/StopwordsList/stopwords_lv.txt @@ -1,167 +1,167 @@ -aiz -ap -ar -apakÅ¡ -Ärpus -augÅ¡pus -bez -caur -dēļ -gar -iekÅ¡ -iz -kopÅ¡ -labad -lejpus -lÄ«dz -no -otrpus -pa -par -pÄr -pÄ“c -pie -pirms -pret -priekÅ¡ -starp -Å¡aipus -uz -viņpus -virs -virspus -zem -apakÅ¡pus -# Conjunctions -un -bet -jo -ja -ka -lai -tomÄ“r -tikko -turpretÄ« -arÄ« -kaut -gan -tÄdēļ -tÄ -ne -tikvien -vien -kÄ -ir -te -vai -kamÄ“r -# Particles -ar -diezin -droÅ¡i -diemžēl -nebÅ«t -ik -it -taÄu -nu -pat -tiklab -iekÅ¡pus -nedz -tik -nevis -turpretim -jeb -iekam -iekÄm -iekÄms -kolÄ«dz -lÄ«dzko -tiklÄ«dz -jebÅ¡u -tÄlab -tÄpÄ“c -nekÄ -itin -jÄ -jau -jel -nÄ“ -nezin -tad -tikai -vis -tak -iekams -vien -# modal verbs -bÅ«t -biju -biji -bija -bijÄm -bijÄt -esmu -esi -esam -esat -būšu -bÅ«si -bÅ«s -bÅ«sim -bÅ«siet -tikt -tiku -tiki -tika -tikÄm -tikÄt -tieku -tiec -tiek -tiekam -tiekat -tikÅ¡u -tiks -tiksim -tiksiet -tapt -tapi -tapÄt -topat -tapÅ¡u -tapsi -taps -tapsim -tapsiet -kļūt -kļuvu -kļuvi -kļuva -kļuvÄm -kļuvÄt -kļūstu -kļūsti -kļūst -kļūstam -kļūstat -kļūšu -kļūsi -kļūs -kļūsim -kļūsiet -# verbs -varÄ“t -varÄ“ju -varÄ“jÄm -varēšu -varÄ“sim -var -varÄ“ji -varÄ“jÄt -varÄ“si -varÄ“siet -varat -varÄ“ja +aiz +ap +ar +apakÅ¡ +Ärpus +augÅ¡pus +bez +caur +dēļ +gar +iekÅ¡ +iz +kopÅ¡ +labad +lejpus +lÄ«dz +no +otrpus +pa +par +pÄr +pÄ“c +pie +pirms +pret +priekÅ¡ +starp +Å¡aipus +uz +viņpus +virs +virspus +zem +apakÅ¡pus +# Conjunctions +un +bet +jo +ja +ka +lai +tomÄ“r +tikko +turpretÄ« +arÄ« +kaut +gan +tÄdēļ +tÄ +ne +tikvien +vien +kÄ +ir +te +vai +kamÄ“r +# Particles +ar +diezin +droÅ¡i +diemžēl +nebÅ«t +ik +it +taÄu +nu +pat +tiklab +iekÅ¡pus +nedz +tik +nevis +turpretim +jeb +iekam +iekÄm +iekÄms +kolÄ«dz +lÄ«dzko +tiklÄ«dz +jebÅ¡u +tÄlab +tÄpÄ“c +nekÄ +itin +jÄ +jau +jel +nÄ“ +nezin +tad +tikai +vis +tak +iekams +vien +# modal verbs +bÅ«t +biju +biji +bija +bijÄm +bijÄt +esmu +esi +esam +esat +būšu +bÅ«si +bÅ«s +bÅ«sim +bÅ«siet +tikt +tiku +tiki +tika +tikÄm +tikÄt +tieku +tiec +tiek +tiekam +tiekat +tikÅ¡u +tiks +tiksim +tiksiet +tapt +tapi +tapÄt +topat +tapÅ¡u +tapsi +taps +tapsim +tapsiet +kļūt +kļuvu +kļuvi +kļuva +kļuvÄm +kļuvÄt +kļūstu +kļūsti +kļūst +kļūstam +kļūstat +kļūšu +kļūsi +kļūs +kļūsim +kļūsiet +# verbs +varÄ“t +varÄ“ju +varÄ“jÄm +varēšu +varÄ“sim +var +varÄ“ji +varÄ“jÄt +varÄ“si +varÄ“siet +varat +varÄ“ja varÄ“s \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_nl.txt b/yake/core/StopwordsList/stopwords_nl.txt similarity index 85% rename from yake/StopwordsList/stopwords_nl.txt rename to yake/core/StopwordsList/stopwords_nl.txt index b7236598..bc8c9019 100644 --- a/yake/StopwordsList/stopwords_nl.txt +++ b/yake/core/StopwordsList/stopwords_nl.txt @@ -1,501 +1,501 @@ -a -aan -aangaande -aangezien -achter -achterna -aen -af -afd -afgelopen -agter -al -aldaar -aldus -alhoewel -alias -alle -allebei -alleen -alleenlyk -allen -alles -als -alsnog -altijd -altoos -altyd -ander -andere -anderen -anders -anderszins -anm -b -behalve -behoudens -beide -beiden -ben -beneden -bent -bepaald -beter -betere -betreffende -bij -bijna -bijvoorbeeld -bijv -binnen -binnenin -bizonder -bizondere -bl -blz -boven -bovenal -bovendien -bovengenoemd -bovenstaand -bovenvermeld -buiten -by -daar -daarheen -daarin -daarna -daarnet -daarom -daarop -daarvanlangs -daer -dan -dat -de -deeze -den -der -ders -derzelver -des -deszelfs -deszelvs -deze -dezelfde -dezelve -dezelven -dezen -dezer -dezulke -die -dien -dikwijls -dikwyls -dit -dl -doch -doen -doet -dog -door -doorgaand -doorgaans -dr -dra -ds -dus -echter -ed -een -eene -eenen -eener -eenig -eenige -eens -eer -eerdat -eerder -eerlang -eerst -eerste -eersten -effe -egter -eigen -eigene -elk -elkanderen -elkanderens -elke -en -enig -enige -enigerlei -enigszins -enkel -enkele -enz -er -erdoor -et -etc -even -eveneens -evenwel -ff -gauw -ge -gebragt -gedurende -geen -geene -geenen -gegeven -gehad -geheel -geheele -gekund -geleden -gelijk -gelyk -gemoeten -gemogen -geven -geweest -gewoon -gewoonweg -geworden -gezegt -gij -gt -gy -haar -had -hadden -hadt -haer -haere -haeren -haerer -hans -hare -heb -hebben -hebt -heeft -hele -hem -hen -het -hier -hierbeneden -hierboven -hierin -hij -hoe -hoewel -hun -hunne -hunner -hy -ibid -idd -ieder -iemand -iet -iets -ii -iig -ik -ikke -ikzelf -in -indien -inmiddels -inz -inzake -is -ja -je -jezelf -jij -jijzelf -jou -jouw -jouwe -juist -jullie -kan -klaar -kon -konden -krachtens -kunnen -kunt -laetste -lang -later -liet -liever -like -m -maar -maeken -maer -mag -martin -me -mede -meer -meesten -men -menigwerf -met -mezelf -mij -mijn -mijnent -mijner -mijzelf -min -minder -misschien -mocht -mochten -moest -moesten -moet -moeten -mogelijk -mogelyk -mogen -my -myn -myne -mynen -myner -myzelf -na -naar -nabij -nadat -naer -net -niet -niets -nimmer -nit -no -noch -nog -nogal -nooit -nr -nu -o -of -ofschoon -om -omdat -omhoog -omlaag -omstreeks -omtrent -omver -onder -ondertussen -ongeveer -ons -onszelf -onze -onzen -onzer -ooit -ook -oorspr -op -opdat -opnieuw -opzij -opzy -over -overeind -overigens -p -pas -pp -precies -pres -prof -publ -reeds -rond -rondom -rug -s -sedert -sinds -sindsdien -sl -slechts -sommige -spoedig -st -steeds -sy -t -tamelijk -tamelyk -te -tegen -tegens -ten -tenzij -ter -terwijl -terwyl -thans -tijdens -toch -toe -toen -toenmaals -toenmalig -tot -totdat -tusschen -tussen -tydens -u -uit -uitg -uitgezonderd -uw -uwe -uwen -uwer -vaak -vaakwat -vakgr -van -vanaf -vandaan -vanuit -vanwege -veel -veeleer -veelen -verder -verre -vert -vervolgens -vgl -vol -volgens -voor -vooraf -vooral -vooralsnog -voorbij -voorby -voordat -voordezen -voordien -voorheen -voorop -voort -voortgez -voorts -voortz -vooruit -vrij -vroeg -vry -waar -waarom -wanneer -want -waren -was -wat -we -weer -weg -wege -wegens -weinig -weinige -wel -weldra -welk -welke -welken -welker -werd -werden -werdt -wezen -wie -wiens -wier -wierd -wierden -wij -wijzelf -wil -wilde -worden -wordt -wy -wyze -wyzelf -zal -ze -zeer -zei -zeker -zekere -zelf -zelfde -zelfs -zelve -zelven -zelvs -zich -zichzelf -zichzelve -zichzelven -zie -zig -zij -zijn -zijnde -zijne -zijner -zo -zo'n -zoals -zodra -zommige -zommigen -zonder -zoo -zou -zoude -zouden -zoveel -zowat -zulk -zulke -zulks -zullen -zult -zy -zyn -zynde -zyne -zynen -zyner +a +aan +aangaande +aangezien +achter +achterna +aen +af +afd +afgelopen +agter +al +aldaar +aldus +alhoewel +alias +alle +allebei +alleen +alleenlyk +allen +alles +als +alsnog +altijd +altoos +altyd +ander +andere +anderen +anders +anderszins +anm +b +behalve +behoudens +beide +beiden +ben +beneden +bent +bepaald +beter +betere +betreffende +bij +bijna +bijvoorbeeld +bijv +binnen +binnenin +bizonder +bizondere +bl +blz +boven +bovenal +bovendien +bovengenoemd +bovenstaand +bovenvermeld +buiten +by +daar +daarheen +daarin +daarna +daarnet +daarom +daarop +daarvanlangs +daer +dan +dat +de +deeze +den +der +ders +derzelver +des +deszelfs +deszelvs +deze +dezelfde +dezelve +dezelven +dezen +dezer +dezulke +die +dien +dikwijls +dikwyls +dit +dl +doch +doen +doet +dog +door +doorgaand +doorgaans +dr +dra +ds +dus +echter +ed +een +eene +eenen +eener +eenig +eenige +eens +eer +eerdat +eerder +eerlang +eerst +eerste +eersten +effe +egter +eigen +eigene +elk +elkanderen +elkanderens +elke +en +enig +enige +enigerlei +enigszins +enkel +enkele +enz +er +erdoor +et +etc +even +eveneens +evenwel +ff +gauw +ge +gebragt +gedurende +geen +geene +geenen +gegeven +gehad +geheel +geheele +gekund +geleden +gelijk +gelyk +gemoeten +gemogen +geven +geweest +gewoon +gewoonweg +geworden +gezegt +gij +gt +gy +haar +had +hadden +hadt +haer +haere +haeren +haerer +hans +hare +heb +hebben +hebt +heeft +hele +hem +hen +het +hier +hierbeneden +hierboven +hierin +hij +hoe +hoewel +hun +hunne +hunner +hy +ibid +idd +ieder +iemand +iet +iets +ii +iig +ik +ikke +ikzelf +in +indien +inmiddels +inz +inzake +is +ja +je +jezelf +jij +jijzelf +jou +jouw +jouwe +juist +jullie +kan +klaar +kon +konden +krachtens +kunnen +kunt +laetste +lang +later +liet +liever +like +m +maar +maeken +maer +mag +martin +me +mede +meer +meesten +men +menigwerf +met +mezelf +mij +mijn +mijnent +mijner +mijzelf +min +minder +misschien +mocht +mochten +moest +moesten +moet +moeten +mogelijk +mogelyk +mogen +my +myn +myne +mynen +myner +myzelf +na +naar +nabij +nadat +naer +net +niet +niets +nimmer +nit +no +noch +nog +nogal +nooit +nr +nu +o +of +ofschoon +om +omdat +omhoog +omlaag +omstreeks +omtrent +omver +onder +ondertussen +ongeveer +ons +onszelf +onze +onzen +onzer +ooit +ook +oorspr +op +opdat +opnieuw +opzij +opzy +over +overeind +overigens +p +pas +pp +precies +pres +prof +publ +reeds +rond +rondom +rug +s +sedert +sinds +sindsdien +sl +slechts +sommige +spoedig +st +steeds +sy +t +tamelijk +tamelyk +te +tegen +tegens +ten +tenzij +ter +terwijl +terwyl +thans +tijdens +toch +toe +toen +toenmaals +toenmalig +tot +totdat +tusschen +tussen +tydens +u +uit +uitg +uitgezonderd +uw +uwe +uwen +uwer +vaak +vaakwat +vakgr +van +vanaf +vandaan +vanuit +vanwege +veel +veeleer +veelen +verder +verre +vert +vervolgens +vgl +vol +volgens +voor +vooraf +vooral +vooralsnog +voorbij +voorby +voordat +voordezen +voordien +voorheen +voorop +voort +voortgez +voorts +voortz +vooruit +vrij +vroeg +vry +waar +waarom +wanneer +want +waren +was +wat +we +weer +weg +wege +wegens +weinig +weinige +wel +weldra +welk +welke +welken +welker +werd +werden +werdt +wezen +wie +wiens +wier +wierd +wierden +wij +wijzelf +wil +wilde +worden +wordt +wy +wyze +wyzelf +zal +ze +zeer +zei +zeker +zekere +zelf +zelfde +zelfs +zelve +zelven +zelvs +zich +zichzelf +zichzelve +zichzelven +zie +zig +zij +zijn +zijnde +zijne +zijner +zo +zo'n +zoals +zodra +zommige +zommigen +zonder +zoo +zou +zoude +zouden +zoveel +zowat +zulk +zulke +zulks +zullen +zult +zy +zyn +zynde +zyne +zynen +zyner zyns \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_no.txt b/yake/core/StopwordsList/stopwords_no.txt similarity index 83% rename from yake/StopwordsList/stopwords_no.txt rename to yake/core/StopwordsList/stopwords_no.txt index e7a444f1..ce8492b5 100644 --- a/yake/StopwordsList/stopwords_no.txt +++ b/yake/core/StopwordsList/stopwords_no.txt @@ -1,119 +1,119 @@ -alle -andre -arbeid -av -begge -bort -bra -bruke -da -denne -der -deres -det -din -disse -du -eller -en -ene -eneste -enhver -enn -er -et -folk -for -fordi -forsÛke -fra -fÃ… -fÛr -fÛrst -gjorde -gjÛre -god -gÃ… -ha -hadde -han -hans -hennes -her -hva -hvem -hver -hvilken -hvis -hvor -hvordan -hvorfor -i -ikke -inn -innen -kan -kunne -lage -lang -lik -like -makt -mange -med -meg -meget -men -mens -mer -mest -min -mye -mÃ… -mÃ…te -navn -nei -ny -nÃ… -nÃ…r -og -ogsÃ… -om -opp -oss -over -part -punkt -pÃ… -rett -riktig -samme -sant -si -siden -sist -skulle -slik -slutt -som -start -stille -sÃ… -tid -til -tilbake -tilstand -under -ut -uten -var -ved -verdi -vi -vil -ville -vite -vÃ…r -vÖre -vÖrt +alle +andre +arbeid +av +begge +bort +bra +bruke +da +denne +der +deres +det +din +disse +du +eller +en +ene +eneste +enhver +enn +er +et +folk +for +fordi +forsÛke +fra +fÃ… +fÛr +fÛrst +gjorde +gjÛre +god +gÃ… +ha +hadde +han +hans +hennes +her +hva +hvem +hver +hvilken +hvis +hvor +hvordan +hvorfor +i +ikke +inn +innen +kan +kunne +lage +lang +lik +like +makt +mange +med +meg +meget +men +mens +mer +mest +min +mye +mÃ… +mÃ…te +navn +nei +ny +nÃ… +nÃ…r +og +ogsÃ… +om +opp +oss +over +part +punkt +pÃ… +rett +riktig +samme +sant +si +siden +sist +skulle +slik +slutt +som +start +stille +sÃ… +tid +til +tilbake +tilstand +under +ut +uten +var +ved +verdi +vi +vil +ville +vite +vÃ…r +vÖre +vÖrt Ã… \ No newline at end of file diff --git a/yake/core/StopwordsList/stopwords_noLang.txt b/yake/core/StopwordsList/stopwords_noLang.txt new file mode 100644 index 00000000..e69de29b diff --git a/yake/StopwordsList/stopwords_pl.txt b/yake/core/StopwordsList/stopwords_pl.txt similarity index 83% rename from yake/StopwordsList/stopwords_pl.txt rename to yake/core/StopwordsList/stopwords_pl.txt index d8853f44..df26b1c6 100644 --- a/yake/StopwordsList/stopwords_pl.txt +++ b/yake/core/StopwordsList/stopwords_pl.txt @@ -1,138 +1,138 @@ -ach -aj -albo -bardzo -bez -bo -być -ci -ciÄ™ -ciebie -co -czy -daleko -dla -dlaczego -dlatego -do -dobrze -dokÄ…d -dość -dużo -dwa -dwaj -dwie -dwoje -dziÅ› -dzisiaj -gdyby -gdzie -go -ich -ile -im -inny -ja -jÄ… -jak -jakby -jaki -je -jeden -jedna -jedno -jego -jej -jemu -jeÅ›li -jest -jestem -jeżeli -już -każdy -kiedy -kierunku -kto -ku -lub -ma -majÄ… -mam -mi -mnÄ… -mnie -moi -mój -moja -moje -może -mu -my -na -nam -nami -nas -nasi -nasz -nasza -nasze -natychmiast -niÄ… -nic -nich -nie -niego -niej -niemu -nigdy -nim -nimi -niż -obok -od -okoÅ‚o -on -ona -one -oni -ono -owszem -po -pod -ponieważ -przed -przedtem -sÄ… -sam -sama -siÄ™ -skÄ…d -tak -taki -tam -ten -to -tobÄ… -tobie -tu -tutaj -twoi -twój -twoja -twoje -ty -wam -wami -was -wasi -wasz -wasza -wasze -we -wiÄ™c -wszystko -wtedy -wy -żaden -zawsze -że +ach +aj +albo +bardzo +bez +bo +być +ci +ciÄ™ +ciebie +co +czy +daleko +dla +dlaczego +dlatego +do +dobrze +dokÄ…d +dość +dużo +dwa +dwaj +dwie +dwoje +dziÅ› +dzisiaj +gdyby +gdzie +go +ich +ile +im +inny +ja +jÄ… +jak +jakby +jaki +je +jeden +jedna +jedno +jego +jej +jemu +jeÅ›li +jest +jestem +jeżeli +już +każdy +kiedy +kierunku +kto +ku +lub +ma +majÄ… +mam +mi +mnÄ… +mnie +moi +mój +moja +moje +może +mu +my +na +nam +nami +nas +nasi +nasz +nasza +nasze +natychmiast +niÄ… +nic +nich +nie +niego +niej +niemu +nigdy +nim +nimi +niż +obok +od +okoÅ‚o +on +ona +one +oni +ono +owszem +po +pod +ponieważ +przed +przedtem +sÄ… +sam +sama +siÄ™ +skÄ…d +tak +taki +tam +ten +to +tobÄ… +tobie +tu +tutaj +twoi +twój +twoja +twoje +ty +wam +wami +was +wasi +wasz +wasza +wasze +we +wiÄ™c +wszystko +wtedy +wy +żaden +zawsze +że diff --git a/yake/StopwordsList/stopwords_pt.txt b/yake/core/StopwordsList/stopwords_pt.txt similarity index 85% rename from yake/StopwordsList/stopwords_pt.txt rename to yake/core/StopwordsList/stopwords_pt.txt index f7df788a..0f2f460f 100644 --- a/yake/StopwordsList/stopwords_pt.txt +++ b/yake/core/StopwordsList/stopwords_pt.txt @@ -1,396 +1,396 @@ -dr -dra -sr -sra -a -à -adeus -agora -aí -ainda -além -algo -algumas -alguns -ali -ano -anos -antes -ao -aos -apenas -apoio -após -aquela -aquelas -aquele -aqueles -aqui -aquilo -área -as -às -assim -até -atrás -através -baixo -bastante -bem -boa -boas -bom -bons -breve -cá -cada -catorze -cedo -cento -certamente -certeza -cima -cinco -coisa -com -como -conselho -contra -custa -da -dá -dão -daquela -daquelas -daquele -daqueles -dar -das -de -debaixo -demais -dentro -depois -desde -dessa -dessas -desse -desses -desta -destas -deste -destes -deve -deverá -dez -dezanove -dezasseis -dezassete -dezoito -dia -diante -diz -dizem -dizer -do -dois -dos -doze -duas -dúvida -e -é -ela -elas -ele -eles -em -embora -entre -era -és -essa -essas -esse -esses -esta -está -estão -estar -estas -estás -estava -este -estes -esteve -estive -estivemos -estiveram -estiveste -estivestes -estou -eu -exemplo -faço -falta -favor -faz -fazeis -fazem -fazemos -fazer -fazes -fez -fim -final -foi -fomos -for -foram -forma -foste -fostes -fui -geral -grande -grandes -grupo -há -hoje -hora -horas -isso -isto -já -lá -lado -local -logo -longe -lugar -maior -maioria -mais -mal -mas -máximo -me -meio -menor -menos -mês -meses -meu -meus -mil -minha -minhas -momento -muito -muitos -na -nada -não -naquela -naquelas -naquele -naqueles -nas -nem -nenhuma -nessa -nessas -nesse -nesses -nesta -nestas -neste -nestes -nível -no -noite -nome -nos -nós -nossa -nossas -nosso -nossos -nova -novas -nove -novo -novos -num -numa -número -nunca -o -obra -obrigada -obrigado -oitava -oitavo -oito -onde -ontem -onze -os -ou -outra -outras -outro -outros -para -parece -parte -partir -paucas -pela -pelas -pelo -pelos -perto -pode -pôde -podem -poder -põe -põem -ponto -pontos -por -porque -porquê -posição -possível -possivelmente -posso -pouca -pouco -poucos -primeira -primeiras -primeiro -primeiros -própria -próprias -próprio -próprios -próxima -próximas -próximo -próximos -puderam -quáis -qual -quando -quanto -quarta -quarto -quatro -que -quê -quem -quer -quereis -querem -queremas -queres -quero -questão -quinta -quinto -quinze -relação -sabe -sabem -são -se -segunda -segundo -sei -seis -sem -sempre -ser -seria -sete -sétima -sétimo -seu -seus -sexta -sexto -sim -sistema -sob -sobre -sois -somos -sou -sua -suas -tal -talvez -também -tanta -tantas -tanto -tão -tarde -te -tem -têm -temos -tendes -tenho -tens -ter -terceira -terceiro -teu -teus -teve -tive -tivemos -tiveram -tiveste -tivestes -toda -todas -todo -todos -trabalho -três -treze -tu -tua -tuas -tudo -um -uma -umas -uns -vai -vais -vão -vários -vem -vêm -vens -ver -vez -vezes -viagem -vindo -vinte -você -vocês -vos -vós -vossa -vossas -vosso -vossos +dr +dra +sr +sra +a +à +adeus +agora +aí +ainda +além +algo +algumas +alguns +ali +ano +anos +antes +ao +aos +apenas +apoio +após +aquela +aquelas +aquele +aqueles +aqui +aquilo +área +as +às +assim +até +atrás +através +baixo +bastante +bem +boa +boas +bom +bons +breve +cá +cada +catorze +cedo +cento +certamente +certeza +cima +cinco +coisa +com +como +conselho +contra +custa +da +dá +dão +daquela +daquelas +daquele +daqueles +dar +das +de +debaixo +demais +dentro +depois +desde +dessa +dessas +desse +desses +desta +destas +deste +destes +deve +deverá +dez +dezanove +dezasseis +dezassete +dezoito +dia +diante +diz +dizem +dizer +do +dois +dos +doze +duas +dúvida +e +é +ela +elas +ele +eles +em +embora +entre +era +és +essa +essas +esse +esses +esta +está +estão +estar +estas +estás +estava +este +estes +esteve +estive +estivemos +estiveram +estiveste +estivestes +estou +eu +exemplo +faço +falta +favor +faz +fazeis +fazem +fazemos +fazer +fazes +fez +fim +final +foi +fomos +for +foram +forma +foste +fostes +fui +geral +grande +grandes +grupo +há +hoje +hora +horas +isso +isto +já +lá +lado +local +logo +longe +lugar +maior +maioria +mais +mal +mas +máximo +me +meio +menor +menos +mês +meses +meu +meus +mil +minha +minhas +momento +muito +muitos +na +nada +não +naquela +naquelas +naquele +naqueles +nas +nem +nenhuma +nessa +nessas +nesse +nesses +nesta +nestas +neste +nestes +nível +no +noite +nome +nos +nós +nossa +nossas +nosso +nossos +nova +novas +nove +novo +novos +num +numa +número +nunca +o +obra +obrigada +obrigado +oitava +oitavo +oito +onde +ontem +onze +os +ou +outra +outras +outro +outros +para +parece +parte +partir +paucas +pela +pelas +pelo +pelos +perto +pode +pôde +podem +poder +põe +põem +ponto +pontos +por +porque +porquê +posição +possível +possivelmente +posso +pouca +pouco +poucos +primeira +primeiras +primeiro +primeiros +própria +próprias +próprio +próprios +próxima +próximas +próximo +próximos +puderam +quáis +qual +quando +quanto +quarta +quarto +quatro +que +quê +quem +quer +quereis +querem +queremas +queres +quero +questão +quinta +quinto +quinze +relação +sabe +sabem +são +se +segunda +segundo +sei +seis +sem +sempre +ser +seria +sete +sétima +sétimo +seu +seus +sexta +sexto +sim +sistema +sob +sobre +sois +somos +sou +sua +suas +tal +talvez +também +tanta +tantas +tanto +tão +tarde +te +tem +têm +temos +tendes +tenho +tens +ter +terceira +terceiro +teu +teus +teve +tive +tivemos +tiveram +tiveste +tivestes +toda +todas +todo +todos +trabalho +três +treze +tu +tua +tuas +tudo +um +uma +umas +uns +vai +vais +vão +vários +vem +vêm +vens +ver +vez +vezes +viagem +vindo +vinte +você +vocês +vos +vós +vossa +vossas +vosso +vossos zero \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_ro.txt b/yake/core/StopwordsList/stopwords_ro.txt similarity index 85% rename from yake/StopwordsList/stopwords_ro.txt rename to yake/core/StopwordsList/stopwords_ro.txt index b84f7618..66d488f5 100644 --- a/yake/StopwordsList/stopwords_ro.txt +++ b/yake/core/StopwordsList/stopwords_ro.txt @@ -1,281 +1,281 @@ -acea -aceasta -această -aceea -acei -aceia -acel -acela -acele -acelea -acest -acesta -aceste -acestea -aceÅŸti -aceÅŸtia -acolo -acord -acum -ai -aia -aibă -aici -al -ăla -ale -alea -ălea -altceva -altcineva -am -ar -are -aÅŸ -aÅŸadar -asemenea -asta -ăsta -astăzi -astea -ăstea -ăştia -asupra -aÅ£i -au -avea -avem -aveÅ£i -azi -bine -bucur -bună -ca -că -căci -când -care -cărei -căror -cărui -cât -câte -câţi -către -câtva -caut -ce -cel -ceva -chiar -cinci -cînd -cine -cineva -cît -cîte -cîţi -cîtva -contra -cu -cum -cumva -curând -curînd -da -dă -dacă -dar -dată -datorită -dau -de -deci -deja -deoarece -departe -deÅŸi -din -dinaintea -dintr- -dintre -doi -doilea -două -drept -după -ea -ei -el -ele -eram -este -eÅŸti -eu -face -fără -fata -fi -fie -fiecare -fii -fim -fiÅ£i -fiu -frumos -graÅ£ie -halbă -iar -ieri -îi -îl -îmi -împotriva -în -înainte -înaintea -încât -încît -încotro -între -întrucât -întrucît -îţi -la -lângă -le -li -lîngă -lor -lui -mă -mai -mâine -mea -mei -mele -mereu -meu -mi -mie -mîine -mine -mult -multă -mulÅ£i -mulÅ£umesc -ne -nevoie -nicăieri -nici -nimeni -nimeri -nimic -niÅŸte -noastră -noastre -noi -noroc -noÅŸtri -nostru -nouă -nu -opt -ori -oricând -oricare -oricât -orice -oricînd -oricine -oricît -oricum -oriunde -până -patra -patru -patrulea -pe -pentru -peste -pic -pînă -poate -pot -prea -prima -primul -prin -puÅ£in -puÅ£ina -puÅ£ină -rog -sa -să -săi -sale -ÅŸapte -ÅŸase -sau -său -se -ÅŸi -sînt -sîntem -sînteÅ£i -spate -spre -ÅŸtiu -sub -sunt -suntem -sunteÅ£i -sută -ta -tăi -tale -tău -te -Å£i -Å£ie -timp -tine -toată -toate -tot -toÅ£i -totuÅŸi -trei -treia -treilea -tu -un -una -unde -undeva -unei -uneia -unele -uneori -unii -unor -unora -unu -unui -unuia -unul -vă -vi -voastră -voastre -voi -voÅŸtri -vostru -vouă -vreme -vreo -vreun -zece -zero -zi +acea +aceasta +această +aceea +acei +aceia +acel +acela +acele +acelea +acest +acesta +aceste +acestea +aceÅŸti +aceÅŸtia +acolo +acord +acum +ai +aia +aibă +aici +al +ăla +ale +alea +ălea +altceva +altcineva +am +ar +are +aÅŸ +aÅŸadar +asemenea +asta +ăsta +astăzi +astea +ăstea +ăştia +asupra +aÅ£i +au +avea +avem +aveÅ£i +azi +bine +bucur +bună +ca +că +căci +când +care +cărei +căror +cărui +cât +câte +câţi +către +câtva +caut +ce +cel +ceva +chiar +cinci +cînd +cine +cineva +cît +cîte +cîţi +cîtva +contra +cu +cum +cumva +curând +curînd +da +dă +dacă +dar +dată +datorită +dau +de +deci +deja +deoarece +departe +deÅŸi +din +dinaintea +dintr- +dintre +doi +doilea +două +drept +după +ea +ei +el +ele +eram +este +eÅŸti +eu +face +fără +fata +fi +fie +fiecare +fii +fim +fiÅ£i +fiu +frumos +graÅ£ie +halbă +iar +ieri +îi +îl +îmi +împotriva +în +înainte +înaintea +încât +încît +încotro +între +întrucât +întrucît +îţi +la +lângă +le +li +lîngă +lor +lui +mă +mai +mâine +mea +mei +mele +mereu +meu +mi +mie +mîine +mine +mult +multă +mulÅ£i +mulÅ£umesc +ne +nevoie +nicăieri +nici +nimeni +nimeri +nimic +niÅŸte +noastră +noastre +noi +noroc +noÅŸtri +nostru +nouă +nu +opt +ori +oricând +oricare +oricât +orice +oricînd +oricine +oricît +oricum +oriunde +până +patra +patru +patrulea +pe +pentru +peste +pic +pînă +poate +pot +prea +prima +primul +prin +puÅ£in +puÅ£ina +puÅ£ină +rog +sa +să +săi +sale +ÅŸapte +ÅŸase +sau +său +se +ÅŸi +sînt +sîntem +sînteÅ£i +spate +spre +ÅŸtiu +sub +sunt +suntem +sunteÅ£i +sută +ta +tăi +tale +tău +te +Å£i +Å£ie +timp +tine +toată +toate +tot +toÅ£i +totuÅŸi +trei +treia +treilea +tu +un +una +unde +undeva +unei +uneia +unele +uneori +unii +unor +unora +unu +unui +unuia +unul +vă +vi +voastră +voastre +voi +voÅŸtri +vostru +vouă +vreme +vreo +vreun +zece +zero +zi zice \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_ru.txt b/yake/core/StopwordsList/stopwords_ru.txt similarity index 91% rename from yake/StopwordsList/stopwords_ru.txt rename to yake/core/StopwordsList/stopwords_ru.txt index d179d8e7..a1a28eca 100644 --- a/yake/StopwordsList/stopwords_ru.txt +++ b/yake/core/StopwordsList/stopwords_ru.txt @@ -1,422 +1,422 @@ -а -е -и -ж -м -о -на -не -ни -об -но -он -мне -мои -мож -она -они -оно -мной -много -многочиÑленное -многочиÑÐ»ÐµÐ½Ð½Ð°Ñ -многочиÑленные -многочиÑленный -мною -мой -мог -могут -можно -может -можхо -мор -Ð¼Ð¾Ñ -моё -мочь -над -нее -оба -нам -нем -нами -ними -мимо -немного -одной -одного -менее -однажды -однако -Ð¼ÐµÐ½Ñ -нему -меньше -ней -наверху -него -ниже -мало -надо -один -одиннадцать -одиннадцатый -назад -наиболее -недавно -миллионов -недалеко -между -низко -Ð¼ÐµÐ»Ñ -Ð½ÐµÐ»ÑŒÐ·Ñ -нибудь -непрерывно -наконец -никогда -никуда -Ð½Ð°Ñ -наш -нет -нею -неё -них -мира -наша -наше -наши -ничего -начала -нередко -неÑколько -обычно -опÑть -около -мы -ну -нх -от -отовÑюду -оÑобенно -нужно -очень -отÑюда -в -во -вон -вниз -внизу -вокруг -вот -воÑемнадцать -воÑемнадцатый -воÑемь -воÑьмой -вверх -вам -вами -важное -Ð²Ð°Ð¶Ð½Ð°Ñ -важные -важный -вдали -везде -ведь -Ð²Ð°Ñ -ваш -ваша -ваше -ваши -впрочем -веÑÑŒ -вдруг -вы -вÑе -второй -вÑем -вÑеми -времени -Ð²Ñ€ÐµÐ¼Ñ -вÑему -вÑего -вÑегда -вÑех -вÑею -вÑÑŽ -вÑÑ -вÑÑ‘ -вÑюду -г -год -говорил -говорит -года -году -где -да -ее -за -из -ли -же -им -до -по -ими -под -иногда -довольно -именно -долго -позже -более -должно -пожалуйÑта -значит -иметь -больше -пока -ему -Ð¸Ð¼Ñ -пор -пора -потом -потому -поÑле -почему -почти -поÑреди -ей -два -две -двенадцать -двенадцатый -двадцать -двадцатый -двух -его -дел -или -без -день -занÑÑ‚ -занÑта -занÑто -занÑты -дейÑтвительно -давно -девÑтнадцать -девÑтнадцатый -девÑть -девÑтый -даже -алло -жизнь -далеко -близко -здеÑÑŒ -дальше -Ð´Ð»Ñ -лет -зато -даром -первый -перед -затем -зачем -лишь -деÑÑть -деÑÑтый -ею -её -их -бы -еще -при -был -про -процентов -против -проÑто -бывает -бывь -еÑли -люди -была -были -было -будем -будет -будете -будешь -прекраÑно -буду -будь -будто -будут -ещё -пÑтнадцать -пÑтнадцатый -друго -другое -другой -другие -Ð´Ñ€ÑƒÐ³Ð°Ñ -других -еÑть -пÑть -быть -лучше -пÑтый -к -ком -конечно -кому -кого -когда -которой -которого -ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ -которые -который -которых -кем -каждое -ÐºÐ°Ð¶Ð´Ð°Ñ -каждые -каждый -кажетÑÑ -как -какой -ÐºÐ°ÐºÐ°Ñ -кто -кроме -куда -кругом -Ñ -Ñ‚ -у -Ñ -та -те -уж -Ñо -то -том -Ñнова -тому -ÑовÑем -того -тогда -тоже -Ñобой -тобой -Ñобою -тобою -Ñначала -только -уметь -тот -тою -хорошо -хотеть -хочешь -хоть -Ñ…Ð¾Ñ‚Ñ -Ñвое -Ñвои -твой -Ñвоей -Ñвоего -Ñвоих -Ñвою -Ñ‚Ð²Ð¾Ñ -твоё -раз -уже -Ñам -там -тем -чем -Ñама -Ñами -теми -Ñамо -рано -Ñамом -Ñамому -Ñамой -Ñамого -Ñемнадцать -Ñемнадцатый -Ñамим -Ñамими -Ñамих -Ñаму -Ñемь -чему -раньше -ÑÐµÐ¹Ñ‡Ð°Ñ -чего -ÑÐµÐ³Ð¾Ð´Ð½Ñ -Ñебе -тебе -Ñеаой -человек -разве -теперь -ÑÐµÐ±Ñ -Ñ‚ÐµÐ±Ñ -Ñедьмой -ÑпаÑибо -Ñлишком -так -такое -такой -такие -также -Ñ‚Ð°ÐºÐ°Ñ -Ñих -тех -чаще -четвертый -через -чаÑто -шеÑтой -шеÑтнадцать -шеÑтнадцатый -шеÑть -четыре -четырнадцать -четырнадцатый -Ñколько -Ñказал -Ñказала -Ñказать -ту -ты -три -Ñта -Ñти -что -Ñто -чтоб -Ñтом -Ñтому -Ñтой -Ñтого -чтобы -Ñтот -Ñтал -туда -Ñтим -Ñтими -Ñ€Ñдом -тринадцать -тринадцатый -Ñтих -третий -тут -Ñту -Ñуть -чуть -тыÑÑч - +а +е +и +ж +м +о +на +не +ни +об +но +он +мне +мои +мож +она +они +оно +мной +много +многочиÑленное +многочиÑÐ»ÐµÐ½Ð½Ð°Ñ +многочиÑленные +многочиÑленный +мною +мой +мог +могут +можно +может +можхо +мор +Ð¼Ð¾Ñ +моё +мочь +над +нее +оба +нам +нем +нами +ними +мимо +немного +одной +одного +менее +однажды +однако +Ð¼ÐµÐ½Ñ +нему +меньше +ней +наверху +него +ниже +мало +надо +один +одиннадцать +одиннадцатый +назад +наиболее +недавно +миллионов +недалеко +между +низко +Ð¼ÐµÐ»Ñ +Ð½ÐµÐ»ÑŒÐ·Ñ +нибудь +непрерывно +наконец +никогда +никуда +Ð½Ð°Ñ +наш +нет +нею +неё +них +мира +наша +наше +наши +ничего +начала +нередко +неÑколько +обычно +опÑть +около +мы +ну +нх +от +отовÑюду +оÑобенно +нужно +очень +отÑюда +в +во +вон +вниз +внизу +вокруг +вот +воÑемнадцать +воÑемнадцатый +воÑемь +воÑьмой +вверх +вам +вами +важное +Ð²Ð°Ð¶Ð½Ð°Ñ +важные +важный +вдали +везде +ведь +Ð²Ð°Ñ +ваш +ваша +ваше +ваши +впрочем +веÑÑŒ +вдруг +вы +вÑе +второй +вÑем +вÑеми +времени +Ð²Ñ€ÐµÐ¼Ñ +вÑему +вÑего +вÑегда +вÑех +вÑею +вÑÑŽ +вÑÑ +вÑÑ‘ +вÑюду +г +год +говорил +говорит +года +году +где +да +ее +за +из +ли +же +им +до +по +ими +под +иногда +довольно +именно +долго +позже +более +должно +пожалуйÑта +значит +иметь +больше +пока +ему +Ð¸Ð¼Ñ +пор +пора +потом +потому +поÑле +почему +почти +поÑреди +ей +два +две +двенадцать +двенадцатый +двадцать +двадцатый +двух +его +дел +или +без +день +занÑÑ‚ +занÑта +занÑто +занÑты +дейÑтвительно +давно +девÑтнадцать +девÑтнадцатый +девÑть +девÑтый +даже +алло +жизнь +далеко +близко +здеÑÑŒ +дальше +Ð´Ð»Ñ +лет +зато +даром +первый +перед +затем +зачем +лишь +деÑÑть +деÑÑтый +ею +её +их +бы +еще +при +был +про +процентов +против +проÑто +бывает +бывь +еÑли +люди +была +были +было +будем +будет +будете +будешь +прекраÑно +буду +будь +будто +будут +ещё +пÑтнадцать +пÑтнадцатый +друго +другое +другой +другие +Ð´Ñ€ÑƒÐ³Ð°Ñ +других +еÑть +пÑть +быть +лучше +пÑтый +к +ком +конечно +кому +кого +когда +которой +которого +ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ +которые +который +которых +кем +каждое +ÐºÐ°Ð¶Ð´Ð°Ñ +каждые +каждый +кажетÑÑ +как +какой +ÐºÐ°ÐºÐ°Ñ +кто +кроме +куда +кругом +Ñ +Ñ‚ +у +Ñ +та +те +уж +Ñо +то +том +Ñнова +тому +ÑовÑем +того +тогда +тоже +Ñобой +тобой +Ñобою +тобою +Ñначала +только +уметь +тот +тою +хорошо +хотеть +хочешь +хоть +Ñ…Ð¾Ñ‚Ñ +Ñвое +Ñвои +твой +Ñвоей +Ñвоего +Ñвоих +Ñвою +Ñ‚Ð²Ð¾Ñ +твоё +раз +уже +Ñам +там +тем +чем +Ñама +Ñами +теми +Ñамо +рано +Ñамом +Ñамому +Ñамой +Ñамого +Ñемнадцать +Ñемнадцатый +Ñамим +Ñамими +Ñамих +Ñаму +Ñемь +чему +раньше +ÑÐµÐ¹Ñ‡Ð°Ñ +чего +ÑÐµÐ³Ð¾Ð´Ð½Ñ +Ñебе +тебе +Ñеаой +человек +разве +теперь +ÑÐµÐ±Ñ +Ñ‚ÐµÐ±Ñ +Ñедьмой +ÑпаÑибо +Ñлишком +так +такое +такой +такие +также +Ñ‚Ð°ÐºÐ°Ñ +Ñих +тех +чаще +четвертый +через +чаÑто +шеÑтой +шеÑтнадцать +шеÑтнадцатый +шеÑть +четыре +четырнадцать +четырнадцатый +Ñколько +Ñказал +Ñказала +Ñказать +ту +ты +три +Ñта +Ñти +что +Ñто +чтоб +Ñтом +Ñтому +Ñтой +Ñтого +чтобы +Ñтот +Ñтал +туда +Ñтим +Ñтими +Ñ€Ñдом +тринадцать +тринадцатый +Ñтих +третий +тут +Ñту +Ñуть +чуть +тыÑÑч + diff --git a/yake/StopwordsList/stopwords_sk.txt b/yake/core/StopwordsList/stopwords_sk.txt similarity index 79% rename from yake/StopwordsList/stopwords_sk.txt rename to yake/core/StopwordsList/stopwords_sk.txt index 687db576..68d7eeb7 100644 --- a/yake/StopwordsList/stopwords_sk.txt +++ b/yake/core/StopwordsList/stopwords_sk.txt @@ -1,110 +1,110 @@ -a -aby -aj -ako -aký -ale -alebo -ani -avšak -ba -bez -buï -cez -do -ho -hoci -i -ich -im -ja -jeho -jej -jemu -ju -k -kam -kde -kedže -keï -kto -ktorý -ku -lebo -ma -mi -mne -mnou -mu -my -mòa -môj -na -nad -nami -neho -nej -nemu -nich -nielen -nim -no -nám -nás -náš -ním -o -od -on -ona -oni -ono -ony -po -pod -pre -pred -pri -s -sa -seba -sem -so -svoj -taký -tam -teba -tebe -tebou -tej -ten -ti -tie -to -toho -tomu -tou -tvoj -ty -tá -tým -v -vami -veï -vo -vy -vám -vás -váš -však -z -za -zo -a -èi -èo -èí -òom -òou -òu +a +aby +aj +ako +aký +ale +alebo +ani +avšak +ba +bez +buï +cez +do +ho +hoci +i +ich +im +ja +jeho +jej +jemu +ju +k +kam +kde +kedže +keï +kto +ktorý +ku +lebo +ma +mi +mne +mnou +mu +my +mòa +môj +na +nad +nami +neho +nej +nemu +nich +nielen +nim +no +nám +nás +náš +ním +o +od +on +ona +oni +ono +ony +po +pod +pre +pred +pri +s +sa +seba +sem +so +svoj +taký +tam +teba +tebe +tebou +tej +ten +ti +tie +to +toho +tomu +tou +tvoj +ty +tá +tým +v +vami +veï +vo +vy +vám +vás +váš +však +z +za +zo +a +èi +èo +èí +òom +òou +òu že \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_sl.txt b/yake/core/StopwordsList/stopwords_sl.txt similarity index 84% rename from yake/StopwordsList/stopwords_sl.txt rename to yake/core/StopwordsList/stopwords_sl.txt index dadaf7f1..03926a08 100644 --- a/yake/StopwordsList/stopwords_sl.txt +++ b/yake/core/StopwordsList/stopwords_sl.txt @@ -1,446 +1,446 @@ -a -ali -april -avgust -b -bi -bil -bila -bile -bili -bilo -biti -blizu -bo -bodo -bojo -bolj -bom -bomo -boste -bova -boÅ¡ -brez -c -cel -cela -celi -celo -d -da -daleÄ -dan -danes -datum -december -deset -deseta -deseti -deseto -devet -deveta -deveti -deveto -do -dober -dobra -dobri -dobro -dokler -dol -dolg -dolga -dolgi -dovolj -drug -druga -drugi -drugo -dva -dve -e -eden -en -ena -ene -eni -enkrat -eno -etc. -f -februar -g -g. -ga -ga. -gor -gospa -gospod -h -halo -i -idr. -ii -iii -in -iv -ix -iz -j -januar -jaz -je -ji -jih -jim -jo -julij -junij -jutri -k -kadarkoli -kaj -kajti -kako -kakor -kamor -kamorkoli -kar -karkoli -katerikoli -kdaj -kdo -kdorkoli -ker -ki -kje -kjer -kjerkoli -ko -koder -koderkoli -koga -komu -kot -kratek -kratka -kratke -kratki -l -lahka -lahke -lahki -lahko -le -lep -lepa -lepe -lepi -lepo -leto -m -maj -majhen -majhna -majhni -malce -malo -manj -marec -me -med -medtem -mene -mesec -mi -midva -midve -mnogo -moj -moja -moje -mora -morajo -moram -moramo -morate -moraÅ¡ -morem -mu -n -na -nad -naj -najina -najino -najmanj -naju -najveÄ -nam -narobe -nas -nato -nazaj -naÅ¡ -naÅ¡a -naÅ¡e -ne -nedavno -nedelja -nek -neka -nekaj -nekatere -nekateri -nekatero -nekdo -neke -nekega -neki -nekje -neko -nekoga -nekoÄ -ni -nikamor -nikdar -nikjer -nikoli -niÄ -nje -njega -njegov -njegova -njegovo -njej -njemu -njen -njena -njeno -nji -njih -njihov -njihova -njihovo -njiju -njim -njo -njun -njuna -njuno -no -nocoj -november -npr. -o -ob -oba -obe -oboje -od -odprt -odprta -odprti -okoli -oktober -on -onadva -one -oni -onidve -osem -osma -osmi -osmo -oz. -p -pa -pet -peta -petek -peti -peto -po -pod -pogosto -poleg -poln -polna -polni -polno -ponavadi -ponedeljek -ponovno -potem -povsod -pozdravljen -pozdravljeni -prav -prava -prave -pravi -pravo -prazen -prazna -prazno -prbl. -precej -pred -prej -preko -pri -pribl. -približno -primer -pripravljen -pripravljena -pripravljeni -proti -prva -prvi -prvo -r -ravno -redko -res -reÄ -s -saj -sam -sama -same -sami -samo -se -sebe -sebi -sedaj -sedem -sedma -sedmi -sedmo -sem -september -seveda -si -sicer -skoraj -skozi -slab -smo -so -sobota -spet -sreda -srednja -srednji -sta -ste -stran -stvar -sva -t -ta -tak -taka -take -taki -tako -takoj -tam -te -tebe -tebi -tega -težak -težka -težki -težko -ti -tista -tiste -tisti -tisto -tj. -tja -to -toda -torek -tretja -tretje -tretji -tri -tu -tudi -tukaj -tvoj -tvoja -tvoje -u -v -vaju -vam -vas -vaÅ¡ -vaÅ¡a -vaÅ¡e -ve -vedno -velik -velika -veliki -veliko -vendar -ves -veÄ -vi -vidva -vii -viii -visok -visoka -visoke -visoki -vsa -vsaj -vsak -vsaka -vsakdo -vsake -vsaki -vsakomur -vse -vsega -vsi -vso -vÄasih -vÄeraj -x -z -za -zadaj -zadnji -zakaj -zaprta -zaprti -zaprto -zdaj -zelo -zunaj -Ä -Äe -Äesto -Äetrta -Äetrtek -Äetrti -Äetrto -Äez -Äigav -Å¡ -Å¡est -Å¡esta -Å¡esti -Å¡esto -Å¡tiri -ž +a +ali +april +avgust +b +bi +bil +bila +bile +bili +bilo +biti +blizu +bo +bodo +bojo +bolj +bom +bomo +boste +bova +boÅ¡ +brez +c +cel +cela +celi +celo +d +da +daleÄ +dan +danes +datum +december +deset +deseta +deseti +deseto +devet +deveta +deveti +deveto +do +dober +dobra +dobri +dobro +dokler +dol +dolg +dolga +dolgi +dovolj +drug +druga +drugi +drugo +dva +dve +e +eden +en +ena +ene +eni +enkrat +eno +etc. +f +februar +g +g. +ga +ga. +gor +gospa +gospod +h +halo +i +idr. +ii +iii +in +iv +ix +iz +j +januar +jaz +je +ji +jih +jim +jo +julij +junij +jutri +k +kadarkoli +kaj +kajti +kako +kakor +kamor +kamorkoli +kar +karkoli +katerikoli +kdaj +kdo +kdorkoli +ker +ki +kje +kjer +kjerkoli +ko +koder +koderkoli +koga +komu +kot +kratek +kratka +kratke +kratki +l +lahka +lahke +lahki +lahko +le +lep +lepa +lepe +lepi +lepo +leto +m +maj +majhen +majhna +majhni +malce +malo +manj +marec +me +med +medtem +mene +mesec +mi +midva +midve +mnogo +moj +moja +moje +mora +morajo +moram +moramo +morate +moraÅ¡ +morem +mu +n +na +nad +naj +najina +najino +najmanj +naju +najveÄ +nam +narobe +nas +nato +nazaj +naÅ¡ +naÅ¡a +naÅ¡e +ne +nedavno +nedelja +nek +neka +nekaj +nekatere +nekateri +nekatero +nekdo +neke +nekega +neki +nekje +neko +nekoga +nekoÄ +ni +nikamor +nikdar +nikjer +nikoli +niÄ +nje +njega +njegov +njegova +njegovo +njej +njemu +njen +njena +njeno +nji +njih +njihov +njihova +njihovo +njiju +njim +njo +njun +njuna +njuno +no +nocoj +november +npr. +o +ob +oba +obe +oboje +od +odprt +odprta +odprti +okoli +oktober +on +onadva +one +oni +onidve +osem +osma +osmi +osmo +oz. +p +pa +pet +peta +petek +peti +peto +po +pod +pogosto +poleg +poln +polna +polni +polno +ponavadi +ponedeljek +ponovno +potem +povsod +pozdravljen +pozdravljeni +prav +prava +prave +pravi +pravo +prazen +prazna +prazno +prbl. +precej +pred +prej +preko +pri +pribl. +približno +primer +pripravljen +pripravljena +pripravljeni +proti +prva +prvi +prvo +r +ravno +redko +res +reÄ +s +saj +sam +sama +same +sami +samo +se +sebe +sebi +sedaj +sedem +sedma +sedmi +sedmo +sem +september +seveda +si +sicer +skoraj +skozi +slab +smo +so +sobota +spet +sreda +srednja +srednji +sta +ste +stran +stvar +sva +t +ta +tak +taka +take +taki +tako +takoj +tam +te +tebe +tebi +tega +težak +težka +težki +težko +ti +tista +tiste +tisti +tisto +tj. +tja +to +toda +torek +tretja +tretje +tretji +tri +tu +tudi +tukaj +tvoj +tvoja +tvoje +u +v +vaju +vam +vas +vaÅ¡ +vaÅ¡a +vaÅ¡e +ve +vedno +velik +velika +veliki +veliko +vendar +ves +veÄ +vi +vidva +vii +viii +visok +visoka +visoke +visoki +vsa +vsaj +vsak +vsaka +vsakdo +vsake +vsaki +vsakomur +vse +vsega +vsi +vso +vÄasih +vÄeraj +x +z +za +zadaj +zadnji +zakaj +zaprta +zaprti +zaprto +zdaj +zelo +zunaj +Ä +Äe +Äesto +Äetrta +Äetrtek +Äetrti +Äetrto +Äez +Äigav +Å¡ +Å¡est +Å¡esta +Å¡esti +Å¡esto +Å¡tiri +ž že \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_sv.txt b/yake/core/StopwordsList/stopwords_sv.txt similarity index 86% rename from yake/StopwordsList/stopwords_sv.txt rename to yake/core/StopwordsList/stopwords_sv.txt index eb21ab80..0fb086f6 100644 --- a/yake/StopwordsList/stopwords_sv.txt +++ b/yake/core/StopwordsList/stopwords_sv.txt @@ -1,386 +1,386 @@ -aderton -adertonde -adjö -aldrig -alla -allas -allt -alltid -alltsÃ¥ -än -andra -andras -annan -annat -ännu -artonde -artonn -Ã¥tminstone -att -Ã¥tta -Ã¥ttio -Ã¥ttionde -Ã¥ttonde -av -även -bÃ¥da -bÃ¥das -bakom -bara -bäst -bättre -behöva -behövas -behövde -behövt -beslut -beslutat -beslutit -bland -blev -bli -blir -blivit -bort -borta -bra -dÃ¥ -dag -dagar -dagarna -dagen -där -därför -de -del -delen -dem -den -deras -dess -det -detta -dig -din -dina -dit -ditt -dock -du -efter -eftersom -elfte -eller -elva -en -enkel -enkelt -enkla -enligt -er -era -ert -ett -ettusen -fÃ¥ -fanns -fÃ¥r -fÃ¥tt -fem -femte -femtio -femtionde -femton -femtonde -fick -fin -finnas -finns -fjärde -fjorton -fjortonde -fler -flera -flesta -följande -för -före -förlÃ¥t -förra -första -fram -framför -frÃ¥n -fyra -fyrtio -fyrtionde -gÃ¥ -gälla -gäller -gällt -gÃ¥r -gärna -gÃ¥tt -genast -genom -gick -gjorde -gjort -god -goda -godare -godast -gör -göra -gott -ha -hade -haft -han -hans -har -här -heller -hellre -helst -helt -henne -hennes -hit -hög -höger -högre -högst -hon -honom -hundra -hundraen -hundraett -hur -i -ibland -idag -igÃ¥r -igen -imorgon -in -inför -inga -ingen -ingenting -inget -innan -inne -inom -inte -inuti -ja -jag -jämfört -kan -kanske -knappast -kom -komma -kommer -kommit -kr -kunde -kunna -kunnat -kvar -länge -längre -lÃ¥ngsam -lÃ¥ngsammare -lÃ¥ngsammast -lÃ¥ngsamt -längst -lÃ¥ngt -lätt -lättare -lättast -legat -ligga -ligger -lika -likställd -likställda -lilla -lite -liten -litet -man -mÃ¥nga -mÃ¥ste -med -mellan -men -mer -mera -mest -mig -min -mina -mindre -minst -mitt -mittemot -möjlig -möjligen -möjligt -möjligtvis -mot -mycket -nÃ¥gon -nÃ¥gonting -nÃ¥got -nÃ¥gra -när -nästa -ned -nederst -nedersta -nedre -nej -ner -ni -nio -nionde -nittio -nittionde -nitton -nittonde -nödvändig -nödvändiga -nödvändigt -nödvändigtvis -nog -noll -nr -nu -nummer -och -ocksÃ¥ -ofta -oftast -olika -olikt -om -oss -över -övermorgon -överst -övre -pÃ¥ -rakt -rätt -redan -sÃ¥ -sade -säga -säger -sagt -samma -sämre -sämst -sedan -senare -senast -sent -sex -sextio -sextionde -sexton -sextonde -sig -sin -sina -sist -sista -siste -sitt -sjätte -sju -sjunde -sjuttio -sjuttionde -sjutton -sjuttonde -ska -skall -skulle -slutligen -smÃ¥ -smÃ¥tt -snart -som -stor -stora -större -störst -stort -tack -tidig -tidigare -tidigast -tidigt -till -tills -tillsammans -tio -tionde -tjugo -tjugoen -tjugoett -tjugonde -tjugotre -tjugotvÃ¥ -tjungo -tolfte -tolv -tre -tredje -trettio -trettionde -tretton -trettonde -tvÃ¥ -tvÃ¥hundra -under -upp -ur -ursäkt -ut -utan -utanför -ute -vad -vänster -vänstra -var -vÃ¥r -vara -vÃ¥ra -varför -varifrÃ¥n -varit -varken -värre -varsÃ¥god -vart -vÃ¥rt -vem -vems -verkligen -vi -vid -vidare -viktig -viktigare -viktigast -viktigt -vilka -vilken -vilket +aderton +adertonde +adjö +aldrig +alla +allas +allt +alltid +alltsÃ¥ +än +andra +andras +annan +annat +ännu +artonde +artonn +Ã¥tminstone +att +Ã¥tta +Ã¥ttio +Ã¥ttionde +Ã¥ttonde +av +även +bÃ¥da +bÃ¥das +bakom +bara +bäst +bättre +behöva +behövas +behövde +behövt +beslut +beslutat +beslutit +bland +blev +bli +blir +blivit +bort +borta +bra +dÃ¥ +dag +dagar +dagarna +dagen +där +därför +de +del +delen +dem +den +deras +dess +det +detta +dig +din +dina +dit +ditt +dock +du +efter +eftersom +elfte +eller +elva +en +enkel +enkelt +enkla +enligt +er +era +ert +ett +ettusen +fÃ¥ +fanns +fÃ¥r +fÃ¥tt +fem +femte +femtio +femtionde +femton +femtonde +fick +fin +finnas +finns +fjärde +fjorton +fjortonde +fler +flera +flesta +följande +för +före +förlÃ¥t +förra +första +fram +framför +frÃ¥n +fyra +fyrtio +fyrtionde +gÃ¥ +gälla +gäller +gällt +gÃ¥r +gärna +gÃ¥tt +genast +genom +gick +gjorde +gjort +god +goda +godare +godast +gör +göra +gott +ha +hade +haft +han +hans +har +här +heller +hellre +helst +helt +henne +hennes +hit +hög +höger +högre +högst +hon +honom +hundra +hundraen +hundraett +hur +i +ibland +idag +igÃ¥r +igen +imorgon +in +inför +inga +ingen +ingenting +inget +innan +inne +inom +inte +inuti +ja +jag +jämfört +kan +kanske +knappast +kom +komma +kommer +kommit +kr +kunde +kunna +kunnat +kvar +länge +längre +lÃ¥ngsam +lÃ¥ngsammare +lÃ¥ngsammast +lÃ¥ngsamt +längst +lÃ¥ngt +lätt +lättare +lättast +legat +ligga +ligger +lika +likställd +likställda +lilla +lite +liten +litet +man +mÃ¥nga +mÃ¥ste +med +mellan +men +mer +mera +mest +mig +min +mina +mindre +minst +mitt +mittemot +möjlig +möjligen +möjligt +möjligtvis +mot +mycket +nÃ¥gon +nÃ¥gonting +nÃ¥got +nÃ¥gra +när +nästa +ned +nederst +nedersta +nedre +nej +ner +ni +nio +nionde +nittio +nittionde +nitton +nittonde +nödvändig +nödvändiga +nödvändigt +nödvändigtvis +nog +noll +nr +nu +nummer +och +ocksÃ¥ +ofta +oftast +olika +olikt +om +oss +över +övermorgon +överst +övre +pÃ¥ +rakt +rätt +redan +sÃ¥ +sade +säga +säger +sagt +samma +sämre +sämst +sedan +senare +senast +sent +sex +sextio +sextionde +sexton +sextonde +sig +sin +sina +sist +sista +siste +sitt +sjätte +sju +sjunde +sjuttio +sjuttionde +sjutton +sjuttonde +ska +skall +skulle +slutligen +smÃ¥ +smÃ¥tt +snart +som +stor +stora +större +störst +stort +tack +tidig +tidigare +tidigast +tidigt +till +tills +tillsammans +tio +tionde +tjugo +tjugoen +tjugoett +tjugonde +tjugotre +tjugotvÃ¥ +tjungo +tolfte +tolv +tre +tredje +trettio +trettionde +tretton +trettonde +tvÃ¥ +tvÃ¥hundra +under +upp +ur +ursäkt +ut +utan +utanför +ute +vad +vänster +vänstra +var +vÃ¥r +vara +vÃ¥ra +varför +varifrÃ¥n +varit +varken +värre +varsÃ¥god +vart +vÃ¥rt +vem +vems +verkligen +vi +vid +vidare +viktig +viktigare +viktigast +viktigt +vilka +vilken +vilket vill \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_tr.txt b/yake/core/StopwordsList/stopwords_tr.txt similarity index 87% rename from yake/StopwordsList/stopwords_tr.txt rename to yake/core/StopwordsList/stopwords_tr.txt index 3097f765..8cc78bbe 100644 --- a/yake/StopwordsList/stopwords_tr.txt +++ b/yake/core/StopwordsList/stopwords_tr.txt @@ -1,212 +1,212 @@ -# Turkish stopwords from LUCENE-559 -# merged with the list from "Information Retrieval on Turkish Texts" -# (http://www.users.muohio.edu/canf/papers/JASIST2008offPrint.pdf) -acaba -altmış -altı -ama -ancak -arada -aslında -ayrıca -bana -bazı -belki -ben -benden -beni -benim -beri -beÅŸ -bile -bin -bir -birçok -biri -birkaç -birkez -birÅŸey -birÅŸeyi -biz -bize -bizden -bizi -bizim -böyle -böylece -bu -buna -bunda -bundan -bunlar -bunları -bunların -bunu -bunun -burada -çok -çünkü -da -daha -dahi -de -defa -deÄŸil -diÄŸer -diye -doksan -dokuz -dolayı -dolayısıyla -dört -edecek -eden -ederek -edilecek -ediliyor -edilmesi -ediyor -eÄŸer -elli -en -etmesi -etti -ettiÄŸi -ettiÄŸini -gibi -göre -halen -hangi -hatta -hem -henüz -hep -hepsi -her -herhangi -herkesin -hiç -hiçbir -için -iki -ile -ilgili -ise -iÅŸte -itibaren -itibariyle -kadar -karşın -katrilyon -kendi -kendilerine -kendini -kendisi -kendisine -kendisini -kez -ki -kim -kimden -kime -kimi -kimse -kırk -milyar -milyon -mu -mü -mı -nasıl -ne -neden -nedenle -nerde -nerede -nereye -niye -niçin -o -olan -olarak -oldu -olduÄŸu -olduÄŸunu -olduklarını -olmadı -olmadığı -olmak -olması -olmayan -olmaz -olsa -olsun -olup -olur -olursa -oluyor -on -ona -ondan -onlar -onlardan -onları -onların -onu -onun -otuz -oysa -öyle -pek -raÄŸmen -sadece -sanki -sekiz -seksen -sen -senden -seni -senin -siz -sizden -sizi -sizin -ÅŸey -ÅŸeyden -ÅŸeyi -ÅŸeyler -şöyle -ÅŸu -ÅŸuna -ÅŸunda -ÅŸundan -ÅŸunları -ÅŸunu -tarafından -trilyon -tüm -üç -üzere -var -vardı -ve -veya -ya -yani -yapacak -yapılan -yapılması -yapıyor -yapmak -yaptı -yaptığı -yaptığını -yaptıkları -yedi -yerine -yetmiÅŸ -yine -yirmi -yoksa -yüz +# Turkish stopwords from LUCENE-559 +# merged with the list from "Information Retrieval on Turkish Texts" +# (http://www.users.muohio.edu/canf/papers/JASIST2008offPrint.pdf) +acaba +altmış +altı +ama +ancak +arada +aslında +ayrıca +bana +bazı +belki +ben +benden +beni +benim +beri +beÅŸ +bile +bin +bir +birçok +biri +birkaç +birkez +birÅŸey +birÅŸeyi +biz +bize +bizden +bizi +bizim +böyle +böylece +bu +buna +bunda +bundan +bunlar +bunları +bunların +bunu +bunun +burada +çok +çünkü +da +daha +dahi +de +defa +deÄŸil +diÄŸer +diye +doksan +dokuz +dolayı +dolayısıyla +dört +edecek +eden +ederek +edilecek +ediliyor +edilmesi +ediyor +eÄŸer +elli +en +etmesi +etti +ettiÄŸi +ettiÄŸini +gibi +göre +halen +hangi +hatta +hem +henüz +hep +hepsi +her +herhangi +herkesin +hiç +hiçbir +için +iki +ile +ilgili +ise +iÅŸte +itibaren +itibariyle +kadar +karşın +katrilyon +kendi +kendilerine +kendini +kendisi +kendisine +kendisini +kez +ki +kim +kimden +kime +kimi +kimse +kırk +milyar +milyon +mu +mü +mı +nasıl +ne +neden +nedenle +nerde +nerede +nereye +niye +niçin +o +olan +olarak +oldu +olduÄŸu +olduÄŸunu +olduklarını +olmadı +olmadığı +olmak +olması +olmayan +olmaz +olsa +olsun +olup +olur +olursa +oluyor +on +ona +ondan +onlar +onlardan +onları +onların +onu +onun +otuz +oysa +öyle +pek +raÄŸmen +sadece +sanki +sekiz +seksen +sen +senden +seni +senin +siz +sizden +sizi +sizin +ÅŸey +ÅŸeyden +ÅŸeyi +ÅŸeyler +şöyle +ÅŸu +ÅŸuna +ÅŸunda +ÅŸundan +ÅŸunları +ÅŸunu +tarafından +trilyon +tüm +üç +üzere +var +vardı +ve +veya +ya +yani +yapacak +yapılan +yapılması +yapıyor +yapmak +yaptı +yaptığı +yaptığını +yaptıkları +yedi +yerine +yetmiÅŸ +yine +yirmi +yoksa +yüz zaten \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_uk.txt b/yake/core/StopwordsList/stopwords_uk.txt similarity index 91% rename from yake/StopwordsList/stopwords_uk.txt rename to yake/core/StopwordsList/stopwords_uk.txt index d331dfda..e561734b 100644 --- a/yake/StopwordsList/stopwords_uk.txt +++ b/yake/core/StopwordsList/stopwords_uk.txt @@ -1,385 +1,385 @@ -a -б -в -г -е -ж -з -м -Ñ‚ -у -Ñ -Ñ” -Ñ– -аж -ви -де -до -за -зі -ми -на -не -ну -нх -ні -по -та -ти -то -ту -ті -це -цю -Ñ†Ñ -ці -чи -ще -що -Ñк -їй -їм -Ñ—Ñ… -Ñ—Ñ— -або -але -ало -без -був -вам -Ð²Ð°Ñ -ваш -вже -вÑе -вÑÑŽ -вÑÑ -від -він -два -дві -Ð´Ð»Ñ -ким -мож -Ð¼Ð¾Ñ -моє -мої -міг -між -мій -над -нам -Ð½Ð°Ñ -наш -нею -неї -них -ніж -ній -оÑÑŒ -при -про -під -пір -раз -рік -Ñам -Ñих -Ñім -так -там -теж -тим -тих -той -тою -три -тут -хоч -хто -цей -цим -цих -Ñ‡Ð°Ñ -щоб -Ñка -Ñкі -адже -буде -буду -будь -була -були -було -бути -вами -ваша -ваше -ваші -веÑÑŒ -вниз -вона -вони -воно -вÑею -вÑім -вÑÑ–Ñ… -втім -геть -далі -двох -день -дуже -зате -його -йому -каже -кого -коли -кому -крім -куди -лише -люди -мало -мати -мене -мені -миру -мною -може -нами -наша -наше -наші -ними -ніби -один -поки -пора -рано -року -році -Ñама -Ñаме -Ñаму -Ñамі -Ñвою -Ñвоє -Ñвої -Ñебе -Ñобі -Ñтав -Ñуть -така -таке -такі -Ñ‚Ð²Ð¾Ñ -твоє -твій -тебе -тими -тобі -того -тоді -тому -туди -хоча -хіба -цими -цієї -чаÑу -чого -чому -Ñкий -Ñких -Ñкої -Ñкщо -ім'Ñ -інша -інше -інші -буває -будеш -більш -вгору -вміти -внизу -віÑім -давно -даром -добре -довго -друго -дÑкую -Ð¶Ð¸Ñ‚Ñ‚Ñ -зараз -знову -ÐºÐ°ÐºÐ°Ñ -кожен -кожна -кожне -кожні -краще -ледве -майже -менше -могти -можна -назад -немає -нижче -нього -однак -п'Ñть -перед -поруч -потім -проти -піÑÐ»Ñ -років -Ñамим -Ñамих -Ñамій -Ñвого -Ñвоєї -Ñвоїх -Ñобою -Ñправ -такий -також -тепер -тиÑÑч -тобою -треба -трохи -уÑюди -уÑіма -хочеш -цього -цьому -чаÑто -через -шіÑть -Ñкого -іноді -інший -інших -багато -будемо -будете -будуть -більше -вÑього -вÑьому -далеко -деÑÑть -доÑить -другий -дійÑно -завжди -звідÑи -зовÑім -кругом -кілька -людина -можуть -навіть -навіщо -нагорі -небудь -низько -ніколи -нікуди -нічого -обидва -одного -однієї -п'Ñтий -перший -проÑто -раніше -раптом -Ñамими -Ñамого -Ñамому -Ñказав -Ñкрізь -Ñьомий -третій -тільки -хотіти -чотири -чудово -шоÑтий -близько -важлива -важливе -важливі -вдалині -воÑьмий -говорив -дев'Ñть -деÑÑтий -зайнÑта -зайнÑто -зайнÑті -занадто -значить -навколо -нарешті -нерідко -повинно -поÑеред -початку -пізніше -Ñказала -Ñказати -Ñкільки -ÑпаÑибі -чаÑтіше -важливий -двадцÑть -дев'Ñтий -зазвичай -зайнÑтий -звичайно -здаєтьÑÑ -найбільш -не можна -недалеко -оÑобливо -потрібно -Ñпочатку -Ñьогодні -чиÑленна -чиÑленне -чиÑленні -відÑотків -двадцÑтий -звідуÑіль -мільйонів -нещодавно -прекраÑно -четвертий -чиÑленний -будь лаÑка -дванадцÑть -одинадцÑть -ÑімнадцÑть -тринадцÑть -безперервно -дванадцÑтий -одинадцÑтий -одного разу -п'ÑтнадцÑть -ÑімнадцÑтий -тринадцÑтий -шіÑтнадцÑть -віÑімнадцÑть -п'ÑтнадцÑтий -чотирнадцÑть -шіÑтнадцÑтий -віÑімнадцÑтий -дев'ÑтнадцÑть -чотирнадцÑтий +a +б +в +г +е +ж +з +м +Ñ‚ +у +Ñ +Ñ” +Ñ– +аж +ви +де +до +за +зі +ми +на +не +ну +нх +ні +по +та +ти +то +ту +ті +це +цю +Ñ†Ñ +ці +чи +ще +що +Ñк +їй +їм +Ñ—Ñ… +Ñ—Ñ— +або +але +ало +без +був +вам +Ð²Ð°Ñ +ваш +вже +вÑе +вÑÑŽ +вÑÑ +від +він +два +дві +Ð´Ð»Ñ +ким +мож +Ð¼Ð¾Ñ +моє +мої +міг +між +мій +над +нам +Ð½Ð°Ñ +наш +нею +неї +них +ніж +ній +оÑÑŒ +при +про +під +пір +раз +рік +Ñам +Ñих +Ñім +так +там +теж +тим +тих +той +тою +три +тут +хоч +хто +цей +цим +цих +Ñ‡Ð°Ñ +щоб +Ñка +Ñкі +адже +буде +буду +будь +була +були +було +бути +вами +ваша +ваше +ваші +веÑÑŒ +вниз +вона +вони +воно +вÑею +вÑім +вÑÑ–Ñ… +втім +геть +далі +двох +день +дуже +зате +його +йому +каже +кого +коли +кому +крім +куди +лише +люди +мало +мати +мене +мені +миру +мною +може +нами +наша +наше +наші +ними +ніби +один +поки +пора +рано +року +році +Ñама +Ñаме +Ñаму +Ñамі +Ñвою +Ñвоє +Ñвої +Ñебе +Ñобі +Ñтав +Ñуть +така +таке +такі +Ñ‚Ð²Ð¾Ñ +твоє +твій +тебе +тими +тобі +того +тоді +тому +туди +хоча +хіба +цими +цієї +чаÑу +чого +чому +Ñкий +Ñких +Ñкої +Ñкщо +ім'Ñ +інша +інше +інші +буває +будеш +більш +вгору +вміти +внизу +віÑім +давно +даром +добре +довго +друго +дÑкую +Ð¶Ð¸Ñ‚Ñ‚Ñ +зараз +знову +ÐºÐ°ÐºÐ°Ñ +кожен +кожна +кожне +кожні +краще +ледве +майже +менше +могти +можна +назад +немає +нижче +нього +однак +п'Ñть +перед +поруч +потім +проти +піÑÐ»Ñ +років +Ñамим +Ñамих +Ñамій +Ñвого +Ñвоєї +Ñвоїх +Ñобою +Ñправ +такий +також +тепер +тиÑÑч +тобою +треба +трохи +уÑюди +уÑіма +хочеш +цього +цьому +чаÑто +через +шіÑть +Ñкого +іноді +інший +інших +багато +будемо +будете +будуть +більше +вÑього +вÑьому +далеко +деÑÑть +доÑить +другий +дійÑно +завжди +звідÑи +зовÑім +кругом +кілька +людина +можуть +навіть +навіщо +нагорі +небудь +низько +ніколи +нікуди +нічого +обидва +одного +однієї +п'Ñтий +перший +проÑто +раніше +раптом +Ñамими +Ñамого +Ñамому +Ñказав +Ñкрізь +Ñьомий +третій +тільки +хотіти +чотири +чудово +шоÑтий +близько +важлива +важливе +важливі +вдалині +воÑьмий +говорив +дев'Ñть +деÑÑтий +зайнÑта +зайнÑто +зайнÑті +занадто +значить +навколо +нарешті +нерідко +повинно +поÑеред +початку +пізніше +Ñказала +Ñказати +Ñкільки +ÑпаÑибі +чаÑтіше +важливий +двадцÑть +дев'Ñтий +зазвичай +зайнÑтий +звичайно +здаєтьÑÑ +найбільш +не можна +недалеко +оÑобливо +потрібно +Ñпочатку +Ñьогодні +чиÑленна +чиÑленне +чиÑленні +відÑотків +двадцÑтий +звідуÑіль +мільйонів +нещодавно +прекраÑно +четвертий +чиÑленний +будь лаÑка +дванадцÑть +одинадцÑть +ÑімнадцÑть +тринадцÑть +безперервно +дванадцÑтий +одинадцÑтий +одного разу +п'ÑтнадцÑть +ÑімнадцÑтий +тринадцÑтий +шіÑтнадцÑть +віÑімнадцÑть +п'ÑтнадцÑтий +чотирнадцÑть +шіÑтнадцÑтий +віÑімнадцÑтий +дев'ÑтнадцÑть +чотирнадцÑтий дев'ÑтнадцÑтий \ No newline at end of file diff --git a/yake/StopwordsList/stopwords_zh.txt b/yake/core/StopwordsList/stopwords_zh.txt similarity index 80% rename from yake/StopwordsList/stopwords_zh.txt rename to yake/core/StopwordsList/stopwords_zh.txt index 955ff2b0..0b3ef8f8 100644 --- a/yake/StopwordsList/stopwords_zh.txt +++ b/yake/core/StopwordsList/stopwords_zh.txt @@ -1,125 +1,125 @@ -çš„ -一 -ä¸ -在 -人 -有 -是 -为 -以 -于 -上 -ä»– -而 -åŽ -之 -æ¥ -åŠ -了 -å›  -下 -å¯ -到 -ç”± -è¿™ -与 -也 -æ­¤ -但 -å¹¶ -个 -å…¶ -å·² -æ—  -å° -我 -们 -èµ· -最 -å† -今 -去 -好 -åª -åˆ -或 -很 -亦 -æŸ -把 -é‚£ -ä½  -乃 -它 -å§ -被 -比 -别 -è¶ -当 -从 -到 -å¾— -打 -凡 -å„¿ -å°” -该 -å„ -ç»™ -è·Ÿ -å’Œ -何 -还 -å³ -几 -æ—¢ -看 -æ® -è· -é  -啦 -了 -å¦ -么 -æ¯ -们 -嘛 -æ‹¿ -哪 -é‚£ -您 -凭 -且 -å´ -让 -ä» -å•¥ -如 -è‹¥ -使 -è° -虽 -éš -åŒ -所 -她 -哇 -å—¡ -å¾€ -哪 -些 -å‘ -沿 -哟 -用 -于 -å’± -则 -怎 -曾 -至 -致 -ç€ -诸 +çš„ +一 +ä¸ +在 +人 +有 +是 +为 +以 +于 +上 +ä»– +而 +åŽ +之 +æ¥ +åŠ +了 +å›  +下 +å¯ +到 +ç”± +è¿™ +与 +也 +æ­¤ +但 +å¹¶ +个 +å…¶ +å·² +æ—  +å° +我 +们 +èµ· +最 +å† +今 +去 +好 +åª +åˆ +或 +很 +亦 +æŸ +把 +é‚£ +ä½  +乃 +它 +å§ +被 +比 +别 +è¶ +当 +从 +到 +å¾— +打 +凡 +å„¿ +å°” +该 +å„ +ç»™ +è·Ÿ +å’Œ +何 +还 +å³ +几 +æ—¢ +看 +æ® +è· +é  +啦 +了 +å¦ +么 +æ¯ +们 +嘛 +æ‹¿ +哪 +é‚£ +您 +凭 +且 +å´ +让 +ä» +å•¥ +如 +è‹¥ +使 +è° +虽 +éš +åŒ +所 +她 +哇 +å—¡ +å¾€ +哪 +些 +å‘ +沿 +哟 +用 +于 +å’± +则 +怎 +曾 +至 +致 +ç€ +诸 自 \ No newline at end of file diff --git a/yake/core/__pycache__/Levenshtein.cpython-310.pyc b/yake/core/__pycache__/Levenshtein.cpython-310.pyc new file mode 100644 index 00000000..9132bea5 Binary files /dev/null and b/yake/core/__pycache__/Levenshtein.cpython-310.pyc differ diff --git a/yake/core/__pycache__/highlight.cpython-310.pyc b/yake/core/__pycache__/highlight.cpython-310.pyc new file mode 100644 index 00000000..51673b91 Binary files /dev/null and b/yake/core/__pycache__/highlight.cpython-310.pyc differ diff --git a/yake/core/__pycache__/yake.cpython-310.pyc b/yake/core/__pycache__/yake.cpython-310.pyc new file mode 100644 index 00000000..c5d843e5 Binary files /dev/null and b/yake/core/__pycache__/yake.cpython-310.pyc differ diff --git a/yake/core/highlight.py b/yake/core/highlight.py new file mode 100644 index 00000000..cddb899e --- /dev/null +++ b/yake/core/highlight.py @@ -0,0 +1,528 @@ +""" +Module for highlighting text based on keywords. + +This module provides functionality to highlight specific keywords within text documents. +It handles both single word (one-gram) and multi-word (n-gram) keyword highlighting, +allowing for flexible text markup based on keyword extraction results. +""" + +import re +import logging +from dataclasses import dataclass +from typing import List + +DEFAULT_HIGHLIGHT_PRE = "" +DEFAULT_HIGHLIGHT_POST = "" + + +@dataclass +class NgramData: + """ + Data structure to hold n-gram processing results. + + This class stores the results of n-gram identification for highlighting, + including the list of words and how they are split within keywords. + + Attributes: + word_list: List of words that form the n-gram + split_kw_list: List of lists containing the split keywords + """ + + word_list: List[str] + split_kw_list: List[List[str]] + + +class TextHighlighter: + """ + Class for highlighting keywords in text. + + This class provides functionality to highlight keywords in text + using pre-defined markers. It supports one-gram and n-gram highlighting, + handling various text patterns and maintaining proper context while + applying highlights. + + Attributes: + See property accessors below for available attributes. + """ + + def __init__( + self, + max_ngram_size, + highlight_pre=DEFAULT_HIGHLIGHT_PRE, + highlight_post=DEFAULT_HIGHLIGHT_POST, + ): + """ + TextHighlighter constructor. Define highlight text snippets. + + Args: + max_ngram_size: Specifies the maximum ngram size in the keywords. + highlight_pre: Specifies the text before a highlighted term. Defaults to . + highlight_post: Specifies the text after a highlighted term. Defaults to . + """ + self.highlight_pre = highlight_pre + self.highlight_post = highlight_post + self.max_ngram_size = max_ngram_size + + def highlight(self, text, keywords): + """ + Highlights keywords in the given text. + + This is the main entry point for text highlighting. It processes the text + and adds highlight markers around identified keywords. + + Args: + text: The original text to be processed. + keywords: A list of keywords to highlight. + Each keyword can be a string or a tuple where the first element is the keyword. + + Returns: + The text with highlighted keywords. + """ + n_text = "" + if len(keywords) > 0: + kw_list = keywords + if isinstance(keywords[0], tuple): + kw_list = [x[0] for x in keywords] + text = text.strip() + if self.max_ngram_size == 1: + n_text = self.format_one_gram_text(text, kw_list) + else: + n_text = self.format_n_gram_text(text, kw_list) + return n_text + + def format_one_gram_text(self, text, relevant_words_array): + """ + Formats text for one-gram highlighting. + + Processes text to highlight individual words that match the keywords, + handling punctuation and maintaining the original text structure. + + Args: + text: The text to process + relevant_words_array: Keywords to highlight + + Returns: + Formatted text with highlighted keywords + """ + text_tokens = text.replace("\n", " ").split(" ") + relevant_words_array = [kw.lower() for kw in relevant_words_array] + try: + for tk, token in enumerate(text_tokens): + kw = re.sub(r'[!",:.;?()]$|^[!",:.;?()]|\W[!",:.;?()]', "", token) + if kw.lower() in relevant_words_array: + text_tokens[tk] = token.replace( + kw, f"{self.highlight_pre}{kw}{self.highlight_post}" + ) + except re.error as e: + logging.error("Regex error: %s", e) + return " ".join(text_tokens) + + def format_n_gram_text(self, text, relevant_words_array): + """ + Formats text for n-gram highlighting. + + Processes text to highlight multi-word phrases that match keywords, + maintaining proper context and handling overlapping keywords. + + Args: + text: The text to process + relevant_words_array: Keywords to highlight + + Returns: + Formatted text with highlighted keywords + """ + text_tokens = text.replace("\n", " ").split(" ") + relevant_words_array = [kw.lower() for kw in relevant_words_array] + + y = 0 + final_splited_text = [] + + while y < len(text_tokens): + n_gram_data = self.find_relevant_ngrams( + y, text_tokens, relevant_words_array + ) + + n_gram_word_list, splited_n_gram_kw_list = n_gram_data + + if n_gram_word_list: + context = { + "splited_n_gram_kw_list": splited_n_gram_kw_list, + "relevant_words_array": relevant_words_array, + "final_splited_text": final_splited_text, + } + y, new_expression = self.process_ngrams( + text_tokens, y, n_gram_word_list, context + ) + final_splited_text.append(new_expression) + else: + final_splited_text.append(text_tokens[y]) + y += 1 + + return " ".join(final_splited_text) + + def find_relevant_ngrams(self, position, text_tokens, relevant_words_array): + """ + Finds relevant n-grams in the text. + + Identifies potential keywords at the current position by looking ahead + for matches with the provided keywords. + + Args: + position: Current position in text tokens + text_tokens: List of tokens from the text + relevant_words_array: Keywords to highlight + + Returns: + Tuple containing n-gram word list and split n-gram keyword list + """ + + ngram_data = self._find_more_relevant_helper( + position, text_tokens, relevant_words_array + ) + + return ngram_data + + def _find_more_relevant_helper(self, position, text_tokens, relevant_words_array): + """ + Helper method for finding relevant n-gram words. + + Checks all possible n-grams starting at the current position and + identifies matches with the provided keywords. + + Args: + position: Current position in text tokens + text_tokens: List of tokens from the text + relevant_words_array: Keywords to highlight + + Returns: + NgramData containing keyword list and split n-gram word list + """ + temporary_list = [] + temporary_list_two = [] + kw_list = [] + splited_n_gram_word_list = [] + + for i in range(self.max_ngram_size): + if position + i < len(text_tokens): + temporary_list.append(text_tokens[position : position + i + 1]) + k = re.sub( + r'[!",:.;?()]$|^[!",:.;?()]|\W[!",:.;?()]', + "", + " ".join(temporary_list[i]), + ) + if k.lower() in relevant_words_array: + temporary_list_two.append(k) + + if temporary_list_two: + sorted_temp = sorted( + temporary_list_two, key=lambda x: relevant_words_array.index(x.lower()) + ) + kw_list.append(sorted_temp[0]) + splited_n_gram_word_list.append(kw_list[0].split()) + + return kw_list, splited_n_gram_word_list + + def process_ngrams(self, text_tokens, position, n_gram_word_list, context): + """ + Processes n-grams and updates the final text. + + Handles the replacing of n-grams with their highlighted versions, + distinguishing between single-word and multi-word keywords. + + Args: + text_tokens: List of tokens from the text + position: Current position in text tokens + n_gram_word_list: List of n-gram words + context: Dictionary containing split n-gram keywords, + relevant words array, and final split text + + Returns: + Tuple containing new position and new expression + """ + if len(n_gram_word_list[0].split(" ")) == 1: + position, new_expression = self.replace_token( + text_tokens, position, n_gram_word_list + ) + else: + ctx = self._create_ngram_context( + n_gram_word_list, + context["splited_n_gram_kw_list"], + context["relevant_words_array"], + context["final_splited_text"], + ) + position, new_expression = self._process_multi_word_ngrams_helper( + text_tokens, position, ctx + ) + + return position, new_expression + + def _create_ngram_context( + self, + n_gram_word_list, + splited_n_gram_kw_list, + relevant_words_array, + final_splited_text, + ): + """ + Creates a context object for n-gram processing. + + Bundles all the necessary information for processing multi-word + ngrams into a single context dictionary. + + Args: + n_gram_word_list: List of n-gram words + splited_n_gram_kw_list: List of split n-gram keywords + relevant_words_array: Keywords to highlight + final_splited_text: List of processed text tokens + + Returns: + Dictionary with context information + """ + return { + "n_gram_word_list": n_gram_word_list, + "splited_n_gram_kw_list": splited_n_gram_kw_list, + "relevant_words_array": relevant_words_array, + "final_splited_text": final_splited_text, + } + + def _process_multi_word_ngrams_helper(self, text_tokens, position, ctx): + """ + Helper method for processing multi-word n-grams. + + Handles the complex logic of identifying and highlighting + multi-word phrases in the text. + + Args: + text_tokens: List of tokens from the text + position: Current position in text tokens + ctx: Context dictionary with processing information + + Returns: + Tuple containing new position and new expression + """ + kw_list = [] + n_gram_word_list = ctx["n_gram_word_list"] + splited_n_gram_kw_list = ctx["splited_n_gram_kw_list"] + relevant_words_array = ctx["relevant_words_array"] + final_splited_text = ctx["final_splited_text"] + + splited_one = n_gram_word_list[0].split() + + for len_kw in range(len(splited_one)): + if position + len_kw < len(text_tokens): + self._update_kw_list( + position + len_kw, + text_tokens, + relevant_words_array, + { + "kw_list": kw_list, + "splited_n_gram_kw_list": splited_n_gram_kw_list, + }, + ) + + if not kw_list: + return position + 1, text_tokens[position] + + min_score_word = min( + kw_list, key=lambda x: relevant_words_array.index(x.lower()) + ) + + if kw_list.index(min_score_word) == 0: + term_list = [min_score_word] + position, new_expression = self.replace_token( + text_tokens, position, term_list + ) + else: + terms_ctx = { + "splited_n_gram_kw_list": splited_n_gram_kw_list, + "min_score_word": min_score_word, + "relevant_words_array": relevant_words_array, + "final_splited_text": final_splited_text, + } + position, new_expression = self._process_relevant_terms_helper( + text_tokens, position, terms_ctx + ) + + return position, new_expression + + def _update_kw_list(self, position, text_tokens, relevant_words_array, kw_dict): + """ + Updates the keyword list and split n-gram keyword list. + + Identifies relevant keywords at a given position and updates + the provided lists with the findings. + + Args: + position: Current position in text tokens + text_tokens: List of tokens from the text + relevant_words_array: Keywords to highlight + kw_dict: Dictionary containing 'kw_list' and 'splited_n_gram_kw_list' + """ + ngram_result = self._find_more_relevant_helper( + position, text_tokens, relevant_words_array + ) + new_kw_list, new_split_list = ngram_result + kw_dict["kw_list"].extend(new_kw_list) + if new_split_list: + kw_dict["splited_n_gram_kw_list"].extend(new_split_list) + + def _process_relevant_terms_helper(self, text_tokens, position, ctx): + """ + Helper method for processing relevant terms. + + Handles the complex logic of determining which terms to highlight + when multiple options are available. + + Args: + text_tokens: List of tokens from the text + position: Current position in text tokens + ctx: Context dictionary with processing information + + Returns: + Tuple containing new position and new expression + """ + splited_n_gram_kw_list = ctx["splited_n_gram_kw_list"] + min_score_word = ctx["min_score_word"] + relevant_words_array = ctx["relevant_words_array"] + final_splited_text = ctx["final_splited_text"] + + if not splited_n_gram_kw_list: + return position + 1, text_tokens[position] + + index_of_more_relevant = splited_n_gram_kw_list[0].index( + min_score_word.split()[0] + ) + temporal_kw = " ".join(splited_n_gram_kw_list[0][:index_of_more_relevant]) + + if temporal_kw.lower() in relevant_words_array: + try: + handle_ctx = { + "temporal_kw": temporal_kw, + "relevant_words_array": relevant_words_array, + "final_splited_text": final_splited_text, + } + return self._handle_temporal_keyword(text_tokens, position, handle_ctx) + except ValueError as e: + print(f"Error: {e}") + term_list = [temporal_kw] + position, new_expression = self.replace_token( + text_tokens, position, term_list + ) + else: + nonrelevant_ctx = { + "splited_n_gram_kw_list": splited_n_gram_kw_list, + "index_of_more_relevant": index_of_more_relevant, + "relevant_words_array": relevant_words_array, + } + position, new_expression = self._handle_nonrelevant_temporal_keyword( + text_tokens, position, nonrelevant_ctx + ) + + return position, new_expression + + def _handle_temporal_keyword(self, text_tokens, position, ctx): + """ + Helper method for handling temporal keywords. + + Determines how to highlight keywords that may span across + multiple tokens or have temporal relationships. + + Args: + text_tokens: List of tokens from the text + position: Current position in text tokens + ctx: Context dictionary with processing information + + Returns: + Tuple containing new position and new expression + """ + temporal_kw = ctx["temporal_kw"] + relevant_words_array = ctx["relevant_words_array"] + final_splited_text = ctx["final_splited_text"] + + if not final_splited_text: + term_list = [temporal_kw] + return self.replace_token(text_tokens, position, term_list) + + last_item = final_splited_text[-1] + combined_kw = f"{last_item} {temporal_kw}" + + if ( + combined_kw.lower() in relevant_words_array + and relevant_words_array.index(temporal_kw.lower()) + > relevant_words_array.index(combined_kw.lower()) + and not re.findall(self.highlight_pre, last_item) + ): + term_list = [combined_kw] + del final_splited_text[-1] + position -= 1 + position, new_expression = self.replace_token( + text_tokens, position, term_list + ) + else: + term_list = [temporal_kw] + position, new_expression = self.replace_token( + text_tokens, position, term_list + ) + + return position, new_expression + + def _handle_nonrelevant_temporal_keyword(self, text_tokens, position, ctx): + """ + Helper method for handling non-relevant temporal keywords. + + Processes keywords that are part of larger phrases but not + relevant on their own. + + Args: + text_tokens: List of tokens from the text + position: Current position in text tokens + ctx: Context dictionary with processing information + + Returns: + Tuple containing new position and new expression + """ + splited_n_gram_kw_list = ctx["splited_n_gram_kw_list"] + index_of_more_relevant = ctx["index_of_more_relevant"] + relevant_words_array = ctx["relevant_words_array"] + + if not splited_n_gram_kw_list: + return position + 1, text_tokens[position] + + for tmp_kw in splited_n_gram_kw_list[0][:index_of_more_relevant]: + if tmp_kw.lower() in relevant_words_array: + term_list = [tmp_kw] + return self.replace_token(text_tokens, position, term_list) + + return position + 1, text_tokens[position] + + def replace_token(self, text_tokens, position, n_gram_word_list): + """ + Replaces tokens in text with highlighted versions. + + Performs the actual replacement of keywords with their highlighted + versions, handling punctuation and maintaining text structure. + + Args: + text_tokens: List of tokens from the text + position: Current position in text tokens + n_gram_word_list: List of n-gram words + + Returns: + Tuple containing new position and new expression + """ + if not n_gram_word_list: + return position + 1, text_tokens[position] + + num_tokens = len(n_gram_word_list[0].split(" ")) + + if position + num_tokens > len(text_tokens): + num_tokens = len(text_tokens) - position + + txt = " ".join(text_tokens[position : position + num_tokens]) + kw_cleaned = re.sub(r'[!",:.;?()]$|^[!",:.;?()]|\W[!",:.;?()]', "", txt) + new_expression = txt.replace( + kw_cleaned, + f"{self.highlight_pre}{n_gram_word_list[0]}{self.highlight_post}", + ) + + return position + num_tokens, new_expression \ No newline at end of file diff --git a/yake/core/yake.py b/yake/core/yake.py new file mode 100644 index 00000000..1d655c3c --- /dev/null +++ b/yake/core/yake.py @@ -0,0 +1,252 @@ +""" +Keyword extraction module for YAKE. + +This module provides the KeywordExtractor class which serves as the main entry point +for the YAKE keyword extraction algorithm. It handles configuration, stopword loading, +deduplication of similar keywords, and the entire extraction pipeline from raw text +to ranked keywords. +""" + +import os +import jellyfish +from yake.data import DataCore +from .Levenshtein import Levenshtein + + +class KeywordExtractor: + """ + Main entry point for YAKE keyword extraction. + + This class handles the configuration, preprocessing, and extraction of keywords + from text documents using statistical features without relying on dictionaries + or external corpora. It integrates components for text processing, candidate + generation, feature extraction, and keyword ranking. + + Attributes: + See initialization parameters for configurable attributes. + """ + + def __init__(self, **kwargs): + """ + Initialize the KeywordExtractor with configuration parameters. + + Args: + **kwargs: Configuration parameters including: + lan (str): Language for stopwords (default: "en") + n (int): Maximum n-gram size (default: 3) + dedup_lim (float): Similarity threshold for deduplication (default: 0.9) + dedup_func (str): Deduplication function: "seqm", "jaro", or "levs" (default: "seqm") + window_size (int): Size of word window for co-occurrence (default: 1) + top (int): Maximum number of keywords to extract (default: 20) + features (list): List of features to use for scoring (default: None = all features) + stopwords (set): Custom set of stopwords (default: None = use language-specific) + """ + # Initialize configuration dictionary with default values + self.config = { + "lan": kwargs.get("lan", "en"), + "n": kwargs.get("n", 3), + "dedup_lim": kwargs.get("dedup_lim", 0.9), + "dedup_func": kwargs.get("dedup_func", "seqm"), + "window_size": kwargs.get("window_size", 1), + "top": kwargs.get("top", 20), + "features": kwargs.get("features", None), + } + + # Load appropriate stopwords and deduplication function + self.stopword_set = self._load_stopwords(kwargs.get("stopwords")) + self.dedup_function = self._get_dedup_function(self.config["dedup_func"]) + + def _load_stopwords(self, stopwords): + """ + Load stopwords from file or use provided set. + + This method handles the loading of language-specific stopwords from + the appropriate resource file, falling back to a language-agnostic + list if the specific language is not available. + + Args: + stopwords (set, optional): Custom set of stopwords to use + + Returns: + set: A set of stopwords for filtering non-content words + """ + # Use provided stopwords if available + if stopwords is not None: + return set(stopwords) + + # Determine the path to the appropriate stopword list + dir_path = os.path.dirname(os.path.realpath(__file__)) + local_path = os.path.join( + "StopwordsList", f"stopwords_{self.config['lan'][:2].lower()}.txt" + ) + + # Fall back to language-agnostic list if specific language not available + if not os.path.exists(os.path.join(dir_path, local_path)): + local_path = os.path.join("StopwordsList", "stopwords_noLang.txt") + + resource_path = os.path.join(dir_path, local_path) + + # Attempt to read the stopword file with UTF-8 encoding + try: + with open(resource_path, encoding="utf-8") as stop_file: + return set(stop_file.read().lower().split("\n")) + except UnicodeDecodeError: + # Fall back to ISO-8859-1 encoding if UTF-8 fails + print("Warning: reading stopword list as ISO-8859-1") + with open(resource_path, encoding="ISO-8859-1") as stop_file: + return set(stop_file.read().lower().split("\n")) + + def _get_dedup_function(self, func_name): + """ + Retrieve the appropriate deduplication function. + + Maps the requested string similarity function name to the corresponding + method implementation for keyword deduplication. + + Args: + func_name (str): Name of the deduplication function to use + + Returns: + function: Reference to the selected string similarity function + """ + # Map function names to their implementations + return { + "jaro_winkler": self.jaro, + "jaro": self.jaro, + "sequencematcher": self.seqm, + "seqm": self.seqm, + }.get(func_name.lower(), self.levs) + + def jaro(self, cand1, cand2): + """ + Calculate Jaro similarity between two strings. + + A string metric measuring edit distance between two sequences, + with higher values indicating greater similarity. + + Args: + cand1 (str): First string to compare + cand2 (str): Second string to compare + + Returns: + float: Similarity score between 0.0 (different) and 1.0 (identical) + """ + return jellyfish.jaro(cand1, cand2) + + def levs(self, cand1, cand2): + """ + Calculate normalized Levenshtein similarity between two strings. + + Computes the Levenshtein distance and normalizes it by the length + of the longer string, returning a similarity score. + + Args: + cand1 (str): First string to compare + cand2 (str): Second string to compare + + Returns: + float: Similarity score between 0.0 (different) and 1.0 (identical) + """ + return 1 - Levenshtein.distance(cand1, cand2) / max(len(cand1), len(cand2)) + + def seqm(self, cand1, cand2): + """ + Calculate sequence matcher ratio between two strings. + + Uses the Levenshtein ratio which measures the similarity between + two strings based on the minimum number of operations required + to transform one string into the other. + + Args: + cand1 (str): First string to compare + cand2 (str): Second string to compare + + Returns: + float: Similarity score between 0.0 (different) and 1.0 (identical) + """ + return Levenshtein.ratio(cand1, cand2) + + def extract_keywords(self, text): + """ + Extract keywords from the given text. + + This function implements the complete YAKE keyword extraction pipeline: + + 1. Preprocesses the input text by normalizing whitespace + 2. Builds a data representation using DataCore, which: + - Tokenizes the text into sentences and words + - Identifies candidate n-grams (1 to n words) + - Creates a graph of term co-occurrences + 3. Extracts statistical features for single terms and n-grams + - For single terms: frequency, position, case, etc. + - For n-grams: combines features from constituent terms + 4. Filters candidates based on validity criteria (e.g., no stopwords at boundaries) + 5. Sorts candidates by their importance score (H), where lower is better + 6. Performs deduplication to remove similar candidates based on string similarity + 7. Returns the top k keywords with their scores + + The algorithm favors keywords that are statistically important but not common + stopwords, with scores reflecting their estimated relevance to the document. + Lower scores indicate more important keywords. + + Args: + text: Input text + + Returns: + List of (keyword, score) tuples sorted by score (lower is better) + + """ + # Handle empty input + if not text: + return [] + + # Normalize text by replacing newlines with spaces + text = text.replace("\n", " ") + + # Create a configuration dictionary for DataCore + core_config = { + "windows_size": self.config["window_size"], + "n": self.config["n"], + } + + # Initialize the data core with the text + dc = DataCore(text=text, stopword_set=self.stopword_set, config=core_config) + + # Build features for single terms and multi-word terms + dc.build_single_terms_features(features=self.config["features"]) + dc.build_mult_terms_features(features=self.config["features"]) + + # Collect and sort all valid candidates by score (lower is better) + result_set = [] + candidates_sorted = sorted( + [cc for cc in dc.candidates.values() if cc.is_valid()], key=lambda c: c.h + ) + + # If deduplication is disabled, return all candidates up to the limit + if self.config["dedup_lim"] >= 1.0: + return [(cand.unique_kw, cand.h) for cand in candidates_sorted][ + : self.config["top"] + ] + + # Perform deduplication by comparing candidates + for cand in candidates_sorted: + should_add = True + # Check if this candidate is too similar to any already selected + for h, cand_result in result_set: + if ( + self.dedup_function(cand.unique_kw, cand_result.unique_kw) + > self.config["dedup_lim"] + ): + should_add = False + break + + # Add candidate if it passes deduplication + if should_add: + result_set.append((cand.h, cand)) + + # Stop once we have enough candidates + if len(result_set) == self.config["top"]: + break + + # Format results as (keyword, score) tuples + return [(cand.kw, h) for (h, cand) in result_set] diff --git a/yake/data/__init__.py b/yake/data/__init__.py new file mode 100644 index 00000000..5a4c9563 --- /dev/null +++ b/yake/data/__init__.py @@ -0,0 +1,7 @@ +"""Data representation module for keyword extraction!""" + +from .core import DataCore +from .single_word import SingleWord +from .composed_word import ComposedWord + +__all__ = ['DataCore', 'SingleWord', 'ComposedWord'] diff --git a/yake/data/__pycache__/__init__.cpython-310.pyc b/yake/data/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 00000000..8fe5344a Binary files /dev/null and b/yake/data/__pycache__/__init__.cpython-310.pyc differ diff --git a/yake/data/__pycache__/composed_word.cpython-310.pyc b/yake/data/__pycache__/composed_word.cpython-310.pyc new file mode 100644 index 00000000..76071d21 Binary files /dev/null and b/yake/data/__pycache__/composed_word.cpython-310.pyc differ diff --git a/yake/data/__pycache__/core.cpython-310.pyc b/yake/data/__pycache__/core.cpython-310.pyc new file mode 100644 index 00000000..4ca9cd21 Binary files /dev/null and b/yake/data/__pycache__/core.cpython-310.pyc differ diff --git a/yake/data/__pycache__/single_word.cpython-310.pyc b/yake/data/__pycache__/single_word.cpython-310.pyc new file mode 100644 index 00000000..1b5318cd Binary files /dev/null and b/yake/data/__pycache__/single_word.cpython-310.pyc differ diff --git a/yake/data/__pycache__/utils.cpython-310.pyc b/yake/data/__pycache__/utils.cpython-310.pyc new file mode 100644 index 00000000..40407216 Binary files /dev/null and b/yake/data/__pycache__/utils.cpython-310.pyc differ diff --git a/yake/data/composed_word.py b/yake/data/composed_word.py new file mode 100644 index 00000000..0ecabb85 --- /dev/null +++ b/yake/data/composed_word.py @@ -0,0 +1,438 @@ +""" +Multi-word term representation module for YAKE keyword extraction. + +This module contains the ComposedWord class which represents multi-word terms +(potential keyword phrases) in a document. It handles the aggregation of features +from individual terms, scoring of candidate phrases, and validation to determine +which phrases make good keyword candidates. +""" + +import numpy as np +import jellyfish +from .utils import STOPWORD_WEIGHT + +class ComposedWord: + """ + Representation of a multi-word term in the document. + + This class stores and aggregates information about multi-word keyword candidates, + calculating combined scores from the properties of their constituent terms. + It tracks statistics like term frequency, integrity, and provides methods to + validate whether a phrase is likely to be a good keyword. + + Attributes: + See property accessors below for available attributes. + """ + + def __init__(self, terms): + """ + Initialize a ComposedWord object representing a multi-word term. + + Args: + terms (list): List of tuples (tag, word, term_obj) representing + the individual words in this phrase. Can be None to + initialize an invalid candidate. + """ + # If terms is None, initialize an invalid candidate + if terms is None: + self.data = { + "start_or_end_stopwords": True, + "tags": set(), + "h": 0.0, + "tf": 0.0, + "kw": "", + "unique_kw": "", + "size": 0, + "terms": [], + "integrity": 0.0, + } + return + + # Basic initialization from terms + self.data = {} + + # Calculate derived properties + self.data["tags"] = set(["".join([w[0] for w in terms])]) + self.data["kw"] = " ".join([w[1] for w in terms]) + self.data["unique_kw"] = self.data["kw"].lower() + self.data["size"] = len(terms) + self.data["terms"] = [w[2] for w in terms if w[2] is not None] + self.data["tf"] = 0.0 + self.data["integrity"] = 1.0 + self.data["h"] = 1.0 + + # Check if the candidate starts or ends with stopwords + if len(self.data["terms"]) > 0: + self.data["start_or_end_stopwords"] = ( + self.data["terms"][0].stopword or self.data["terms"][-1].stopword + ) + else: + self.data["start_or_end_stopwords"] = True + + # Property accessors for backward compatibility + @property + def tags(self): + """Get the set of part-of-speech tag sequences for this phrase.""" + return self.data["tags"] + + @property + def kw(self): + """Get the original form of the keyword phrase.""" + return self.data["kw"] + + @property + def unique_kw(self): + """Get the normalized (lowercase) form of the keyword phrase.""" + return self.data["unique_kw"] + + @property + def size(self): + """Get the number of words in this phrase.""" + return self.data["size"] + + @property + def terms(self): + """Get the list of SingleWord objects for each constituent term.""" + return self.data["terms"] + + @property + def tf(self): + """Get the term frequency (number of occurrences) in the document.""" + return self.data["tf"] + + @tf.setter + def tf(self, value): + """ + Set the term frequency value. + + Args: + value (float): The new term frequency value + """ + self.data["tf"] = value + + @property + def integrity(self): + """Get the integrity score indicating phrase coherence.""" + return self.data["integrity"] + + @property + def h(self): + """Get the final relevance score of this phrase (lower is better).""" + return self.data["h"] + + @h.setter + def h(self, value): + """ + Set the final relevance score of this phrase. + + Args: + value (float): The new score value + """ + self.data["h"] = value + + @property + def start_or_end_stopwords(self): + """Get whether this phrase starts or ends with stopwords.""" + return self.data["start_or_end_stopwords"] + + def uptade_cand(self, cand): + """ + Update this candidate with data from another candidate. + + Merges tag information from another candidate representing + the same keyword phrase. + + Args: + cand (ComposedWord): Another instance of the same keyword to merge with + """ + # Add all tags from the other candidate to this one's tags + for tag in cand.tags: + self.tags.add(tag) + + def is_valid(self): + """ + Check if this candidate is a valid keyword phrase. + + A valid keyword phrase doesn't contain unusual characters or digits, + and doesn't start or end with stopwords. + + Returns: + bool: True if this is a valid keyword candidate, False otherwise + """ + is_valid = False + # Check that at least one tag sequence has no unusual characters or digits + for tag in self.tags: + is_valid = is_valid or ("u" not in tag and "d" not in tag) + + # A valid keyword cannot start or end with a stopword + return is_valid and not self.start_or_end_stopwords + + def get_composed_feature(self, feature_name, discart_stopword=True): + """ + Get composed feature values for the n-gram. + + This function aggregates a specific feature across all terms in the n-gram. + It computes the sum, product, and ratio of the feature values, optionally + excluding stopwords from the calculation. + + Args: + feature_name: Name of feature to get (must be an attribute of the term objects) + discard_stopword: Whether to exclude stopwords from calculation (True by default) + + Returns: + Tuple of (sum, product, ratio) for the feature where: + - sum: Sum of the feature values across all relevant terms + - product: Product of the feature values across all relevant terms + - ratio: Product divided by (sum + 1), a measure of feature consistency + + """ + # Get feature values from each term, filtering stopwords if requested + list_of_features = [ + getattr(term, feature_name) + for term in self.terms + if (discart_stopword and not term.stopword) or not discart_stopword + ] + + # Calculate aggregate statistics + sum_f = sum(list_of_features) + prod_f = np.prod(list_of_features) + + # Return the three aggregated values + return (sum_f, prod_f, prod_f / (sum_f + 1)) + + def build_features(self, params): + """ + Build features for machine learning or evaluation. + + Generates feature vectors that can be used for model training, + evaluation, or visualization of keyword properties. + + Args: + params (dict): Parameters for feature generation including: + - features (list): Features to include + - _stopword (list): Whether to consider stopwords [True, False] + - doc_id (str): Document identifier + - keys (list): Gold standard keywords for evaluation + - rel (bool): Whether to include relevance feature + - rel_approx (bool): Whether to include approximate relevance + - is_virtual (bool): Whether this is a virtual candidate + + Returns: + tuple: (features_list, column_names, matched_gold_standards) + """ + # Get feature configuration from parameters + features = params.get( + "features", ["wfreq", "wrel", "tf", "wcase", "wpos", "wspread"] + ) + _stopword = params.get("_stopword", [True, False]) + + # Use defaults if not provided + if features is None: + features = ["wfreq", "wrel", "tf", "wcase", "wpos", "wspread"] + if _stopword is None: + _stopword = [True, False] + + # Initialize feature collection + columns = [] + features_cand = [] + seen = set() + + # Add document identifier if provided + if params.get("doc_id") is not None: + columns.append("doc_id") + features_cand.append(params["doc_id"]) + + # Add gold standard match features if keys are provided + if params.get("keys") is not None: + # Exact match feature + if params.get("rel", True): + columns.append("rel") + if self.unique_kw in params["keys"] or params.get("is_virtual", False): + features_cand.append(1) + seen.add(self.unique_kw) + else: + features_cand.append(0) + + # Approximate match feature using string similarity + if params.get("rel_approx", True): + columns.append("rel_approx") + max_gold_ = ("", 0.0) + for gold_key in params["keys"]: + # Calculate normalized Levenshtein similarity + dist = 1.0 - jellyfish.levenshtein_distance( + gold_key, + self.unique_kw, + ) / max(len(gold_key), len(self.unique_kw)) + max_gold_ = (gold_key, dist) + features_cand.append(max_gold_[1]) + features_cand.append(max_gold_[1]) + + # Add basic candidate properties + columns.append("kw") + features_cand.append(self.unique_kw) + columns.append("h") + features_cand.append(self.h) + columns.append("tf") + features_cand.append(self.tf) + columns.append("size") + features_cand.append(self.size) + columns.append("is_virtual") + columns.append("is_virtual") + features_cand.append(int(params.get("is_virtual", False))) + + # Add all requested features with different stopword handling + for feature_name in features: + for discart_stopword in _stopword: + # Calculate aggregate feature metrics + (f_sum, f_prod, f_sum_prod) = self.get_composed_feature( + feature_name, discart_stopword=discart_stopword + ) + + # Add sum feature + columns.append( + f"{'n' if discart_stopword else ''}s_sum_K{feature_name}" + ) + features_cand.append(f_sum) + + # Add product feature + columns.append( + f"{'n' if discart_stopword else ''}s_prod_K{feature_name}" + ) + features_cand.append(f_prod) + + # Add sum-product feature + columns.append( + f"{'n' if discart_stopword else ''}s_sum_prod_K{feature_name}" + ) + features_cand.append(f_sum_prod) + + return (features_cand, columns, seen) + + def update_h(self, features=None, is_virtual=False): + """ + Update the term's score based on its constituent terms. + + Calculates a combined relevance score for the multi-word term by + aggregating scores of its constituent words, with special handling for + stopwords to improve keyword quality. + + Args: + features (list, optional): Specific features to use for scoring + is_virtual (bool): Whether this is a virtual candidate not in text + """ + sum_h = 0.0 + prod_h = 1.0 + + # Process each term in the phrase + for t, term_base in enumerate(self.terms): + # Handle non-stopwords directly + if not term_base.stopword: + sum_h += term_base.h + prod_h *= term_base.h + + # Handle stopwords according to configured weight method + else: + if STOPWORD_WEIGHT == "bi": + # BiWeight: use probabilities of adjacent term connections + prob_t1 = 0.0 + # Check connection with previous term + if t > 0 and term_base.g.has_edge( + self.terms[t - 1].id, self.terms[t].id + ): + prob_t1 = ( + term_base.g[self.terms[t - 1].id][self.terms[t].id]["tf"] + / self.terms[t - 1].tf + ) + + prob_t2 = 0.0 + # Check connection with next term + if t < len(self.terms) - 1 and term_base.g.has_edge( + self.terms[t].id, self.terms[t + 1].id + ): + prob_t2 = ( + term_base.g[self.terms[t].id][self.terms[t + 1].id]["tf"] + / self.terms[t + 1].tf + ) + + # Calculate combined probability and update scores + prob = prob_t1 * prob_t2 + prod_h *= 1 + (1 - prob) + sum_h -= 1 - prob + elif STOPWORD_WEIGHT == "h": + # HWeight: treat stopwords like normal words + sum_h += term_base.h + prod_h *= term_base.h + elif STOPWORD_WEIGHT == "none": + # None: ignore stopwords entirely + pass + + # Determine term frequency to use in scoring + tf_used = 1.0 + if features is None or "KPF" in features: + tf_used = self.tf + + # For virtual candidates, use mean frequency of constituent terms + if is_virtual: + tf_used = np.mean([term_obj.tf for term_obj in self.terms]) + + # Calculate final score (lower is better) + self.h = prod_h / ((sum_h + 1) * tf_used) + + def update_h_old(self, features=None, is_virtual=False): + """ + Legacy method for updating the term's score. + + Preserved for backward compatibility but uses a slightly different + approach to calculate scores. + + Args: + features (list, optional): Specific features to use for scoring + is_virtual (bool): Whether this is a virtual candidate not in text + """ + sum_h = 0.0 + prod_h = 1.0 + + # Process each term in the phrase + for t, term_base in enumerate(self.terms): + # Skip terms with zero frequency in virtual candidates + if is_virtual and term_base.tf == 0: + continue + + # Handle stopwords with probability-based weighting + if term_base.stopword: + # Calculate probability of co-occurrence with previous term + prob_t1 = 0.0 + if term_base.g.has_edge(self.terms[t - 1].id, self.terms[t].id): + prob_t1 = ( + term_base.g[self.terms[t - 1].id][self.terms[t].id]["tf"] + / self.terms[t - 1].tf + ) + + # Calculate probability of co-occurrence with next term + prob_t2 = 0.0 + if term_base.g.has_edge(self.terms[t].id, self.terms[t + 1].id): + prob_t2 = ( + term_base.g[self.terms[t].id][self.terms[t + 1].id]["tf"] + / self.terms[t + 1].tf + ) + + # Update scores based on combined probability + prob = prob_t1 * prob_t2 + prod_h *= 1 + (1 - prob) + sum_h -= 1 - prob + else: + # Handle normal words directly + sum_h += term_base.h + prod_h *= term_base.h + + # Determine term frequency to use in scoring + tf_used = 1.0 + if features is None or "KPF" in features: + tf_used = self.tf + + # For virtual candidates, use mean frequency of constituent terms + if is_virtual: + tf_used = np.mean([term_obj.tf for term_obj in self.terms]) + + # Calculate final score (lower is better) + self.h = prod_h / ((sum_h + 1) * tf_used) diff --git a/yake/data/core.py b/yake/data/core.py new file mode 100644 index 00000000..9eb72f70 --- /dev/null +++ b/yake/data/core.py @@ -0,0 +1,560 @@ +""" +Core data representation module for YAKE keyword extraction. + +This module contains the DataCore class which serves as the foundation for +processing and analyzing text documents to extract keywords. It handles text +preprocessing, term identification, co-occurrence analysis, and candidate +keyword generation. +""" + +import string +import networkx as nx +import numpy as np + +from segtok.tokenizer import web_tokenizer, split_contractions +from .utils import pre_filter, tokenize_sentences, get_tag +from .single_word import SingleWord +from .composed_word import ComposedWord + +class DataCore: + """ + Core data representation for document analysis and keyword extraction. + + This class processes text documents to identify potential keywords based on + statistical features and contextual relationships between terms. It maintains + the document's structure, processes individual terms, and generates candidate + keywords. + + Attributes: + See property accessors below for available attributes. + """ + + def __init__(self, text, stopword_set, config=None): + """ + Initialize the data core with text and configuration. + + Args: + text (str): The input text to analyze for keyword extraction + stopword_set (set): A set of stopwords to filter out non-content words + config (dict, optional): Configuration options including: + - windows_size (int): Size of word window for co-occurrence (default: 2) + - n (int): Maximum length of keyword phrases (default: 3) + - tags_to_discard (set): POS tags to ignore (default: {"u", "d"}) + - exclude (set): Characters to exclude (default: string.punctuation) + """ + # Initialize default configuration if none provided + if config is None: + config = {} + + # Extract configuration values with appropriate defaults + windows_size = config.get("windows_size", 2) + n = config.get("n", 3) + tags_to_discard = config.get("tags_to_discard", set(["u", "d"])) + exclude = config.get("exclude", set(string.punctuation)) + + # Initialize the state dictionary containing all component data structures + self._state = { + # Configuration settings + "config": { + "exclude": exclude, # Punctuation and other characters to exclude + "tags_to_discard": tags_to_discard, # POS tags to ignore during analysis + "stopword_set": stopword_set # Set of stopwords for filtering + }, + + # Text corpus statistics + "text_stats": { + "number_of_sentences": 0, # Total count of sentences + "number_of_words": 0 # Total count of processed words + }, + + # Core data collections for analysis + "collections": { + "terms": {}, # Dictionary mapping terms to SingleWord objects + "candidates": {}, # Dictionary mapping unique keywords to ComposedWord objects + "sentences_obj": [], # Nested list of processed sentence objects + "sentences_str": [], # List of raw sentence strings + "freq_ns": {} # Frequency distribution of n-grams by length + }, + + # Graph for term co-occurrence analysis + "g": nx.DiGraph() # Directed graph where nodes are terms and edges represent co-occurrences + } + + # Initialize n-gram frequencies with zero counts for each length 1 to n + for i in range(n): + self._state["collections"]["freq_ns"][i + 1] = 0.0 + + # Process the text and build all data structures + self._build(text, windows_size, n) + + # --- Property accessors for backward compatibility --- + + # Configuration properties + @property + def exclude(self): + """Get the set of characters to exclude from processing.""" + return self._state["config"]["exclude"] + + @property + def tags_to_discard(self): + """Get the set of part-of-speech tags to ignore during analysis.""" + return self._state["config"]["tags_to_discard"] + + @property + def stopword_set(self): + """Get the set of stopwords used for filtering.""" + return self._state["config"]["stopword_set"] + + @property + def g(self): + """Get the directed graph representing term co-occurrences.""" + return self._state["g"] + + # Text statistics properties + @property + def number_of_sentences(self): + """Get the total number of sentences in the document.""" + return self._state["text_stats"]["number_of_sentences"] + + @number_of_sentences.setter + def number_of_sentences(self, value): + """Set the total number of sentences in the document.""" + self._state["text_stats"]["number_of_sentences"] = value + + @property + def number_of_words(self): + """Get the total number of words processed in the document.""" + return self._state["text_stats"]["number_of_words"] + + @number_of_words.setter + def number_of_words(self, value): + """Set the total number of words processed in the document.""" + self._state["text_stats"]["number_of_words"] = value + + # Collection properties + @property + def terms(self): + """Get the dictionary of SingleWord objects representing individual terms.""" + return self._state["collections"]["terms"] + + @property + def candidates(self): + """Get the dictionary of ComposedWord objects representing keyword candidates.""" + return self._state["collections"]["candidates"] + + @property + def sentences_obj(self): + """Get the nested list of processed sentence objects.""" + return self._state["collections"]["sentences_obj"] + + @property + def sentences_str(self): + """Get the list of raw sentence strings.""" + return self._state["collections"]["sentences_str"] + + @sentences_str.setter + def sentences_str(self, value): + """Set the list of raw sentence strings.""" + self._state["collections"]["sentences_str"] = value + + @property + def freq_ns(self): + """Get the frequency distribution of n-grams by length.""" + return self._state["collections"]["freq_ns"] + + # --- Internal utility methods --- + def _build(self, text, windows_size, n): + """ + Build the core data structures from the input text. + + This method handles the initial processing of text, including + pre-filtering, sentence segmentation, and word tokenization. + + Args: + text (str): The input text to process + windows_size (int): Size of word window for co-occurrence analysis + n (int): Maximum n-gram length to consider for keyword candidates + """ + # Pre-process text for normalization + text = pre_filter(text) + + # Split text into sentences and tokenize + self.sentences_str = tokenize_sentences(text) + self.number_of_sentences = len(self.sentences_str) + + # Initialize position counter for global word positions + pos_text = 0 + + # Create a processing context dictionary to pass fewer arguments + context = {"windows_size": windows_size, "n": n} + + # Process each sentence individually + for sentence_id, sentence in enumerate(self.sentences_str): + pos_text = self._process_sentence(sentence, sentence_id, pos_text, context) + + # Store the total number of processed words + self.number_of_words = pos_text + + def _process_sentence(self, sentence, sentence_id, pos_text, context): + """ + Process a single sentence from the document. + + Handles the tokenization of a sentence, identifies words and punctuation, + and processes each meaningful word. + + Args: + sentence (list): List of word tokens in the sentence + sentence_id (int): Unique identifier for this sentence + pos_text (int): Current global position in the text + context (dict): Processing context with configuration parameters + + Returns: + int: Updated global position counter + """ + # Initialize lists to store processed sentence components + sentence_obj_aux = [] # Blocks of words within the sentence + block_of_word_obj = [] # Current block of continuous words (separated by punctuation) + + # Extend the context with sentence information for word processing + processing_context = context.copy() + processing_context["sentence_id"] = sentence_id + + # Process each word in the sentence + for pos_sent, word in enumerate(sentence): + # Check if the word is just punctuation (all characters are excluded) + if len([c for c in word if c in self.exclude]) == len(word): + # If we have a block of words, save it and start a new block + if len(block_of_word_obj) > 0: + sentence_obj_aux.append(block_of_word_obj) + block_of_word_obj = [] + else: + # Process meaningful words + word_context = { + "pos_sent": pos_sent, # Position within the sentence + "block_of_word_obj": block_of_word_obj, # Current word block + } + # Process this word and update position counter + pos_text = self._process_word( + word, pos_text, processing_context, word_context + ) + + # Save any remaining word block + if len(block_of_word_obj) > 0: + sentence_obj_aux.append(block_of_word_obj) + + # Add processed sentence to collection if not empty + if len(sentence_obj_aux) > 0: + self.sentences_obj.append(sentence_obj_aux) + + return pos_text + + def _process_word(self, word, pos_text, context, word_context): + """ + Process a single word within a sentence. + + Creates or retrieves the term object, updates its occurrences, + analyzes co-occurrences with nearby words, and generates candidate keywords. + + Args: + word (str): The word to process + pos_text (int): Current global position in the text + context (dict): Processing context with configuration parameters + word_context (dict): Word-specific context information + + Returns: + int: Updated global position counter + """ + # Extract necessary context variables + sentence_id = context["sentence_id"] + windows_size = context["windows_size"] + n = context["n"] + pos_sent = word_context["pos_sent"] + block_of_word_obj = word_context["block_of_word_obj"] + + # Get the part-of-speech tag for this word + tag = self.get_tag(word, pos_sent) + + # Get or create the term object for this word + term_obj = self.get_term(word) + + # Add this occurrence to the term's record + term_obj.add_occur(tag, sentence_id, pos_sent, pos_text) + + # Increment global position counter + pos_text += 1 + + # Update co-occurrence information for valid tags + if tag not in self.tags_to_discard: + self._update_cooccurrence(block_of_word_obj, term_obj, windows_size) + + # Generate keyword candidates involving this term + self._generate_candidates((tag, word), term_obj, block_of_word_obj, n) + + # Add this word to the current block + block_of_word_obj.append((tag, word, term_obj)) + + return pos_text + + def _update_cooccurrence(self, block_of_word_obj, term_obj, windows_size): + """ + Update co-occurrence information between terms. + + Records relationships between the current term and previous terms + within the specified window size. + + Args: + block_of_word_obj (list): Current block of words + term_obj (SingleWord): Term object for the current word + windows_size (int): Size of co-occurrence window to consider + """ + # Calculate the window of previous words to consider for co-occurrence + word_windows = list( + range(max(0, len(block_of_word_obj) - windows_size), len(block_of_word_obj)) + ) + + # For each word in the window, update co-occurrence if it's a valid term + for w in word_windows: + if block_of_word_obj[w][0] not in self.tags_to_discard: + # Add co-occurrence edge from previous term to current term + self.add_cooccur(block_of_word_obj[w][2], term_obj) + + def _generate_candidates(self, term, term_obj, block_of_word_obj, n): + """ + Generate keyword candidates from terms. + + Creates single-term candidates and multi-term candidates up to length n, + combining the current term with previous terms. + + Args: + term (tuple): Current term as (tag, word) tuple + term_obj (SingleWord): Term object for the current word + block_of_word_obj (list): Current block of words + n (int): Maximum candidate length to generate + """ + # Create single-term candidate + candidate = [term + (term_obj,)] + cand = ComposedWord(candidate) + self.add_or_update_composedword(cand) + + # Calculate window of previous words to consider for multi-term candidates + word_windows = list( + range(max(0, len(block_of_word_obj) - (n - 1)), len(block_of_word_obj)) + )[::-1] # Reverse to build phrases from right to left + + # Generate multi-term candidates with increasing length + for w in word_windows: + # Add previous term to candidate + candidate.append(block_of_word_obj[w]) + + # Update frequency count for this n-gram length + self.freq_ns[len(candidate)] += 1.0 + + # Create and register the composed word candidate + # (reverse to maintain correct word order) + cand = ComposedWord(candidate[::-1]) + self.add_or_update_composedword(cand) + + # --- Public API methods --- + + def get_tag(self, word, i): + """ + Get the part-of-speech tag for a word. + + Args: + word (str): The word to tag + i (int): Position of the word in its sentence + + Returns: + str: Single character tag representing the word type + ("d" for digit, "u" for unusual, "a" for acronym, + "n" for proper noun, "p" for plain word) + """ + return get_tag(word, i, self.exclude) + + def build_candidate(self, candidate_string): + """ + Build a candidate ComposedWord from a string. + + This function processes a candidate string by tokenizing it, tagging each word, + and creating a ComposedWord object from the resulting terms. It's used to + convert external strings into the internal candidate representation. + + Args: + candidate_string (str): String to convert to a keyword candidate + + Returns: + ComposedWord: A composed word object representing the candidate + """ + + # Tokenize the candidate string + tokenized_words = [ + w + for w in split_contractions(web_tokenizer(candidate_string.lower())) + if not (w.startswith("'") and len(w) > 1) and len(w) > 0 + ] + + # Process each word in the candidate + candidate_terms = [] + for index, word in enumerate(tokenized_words): + # Get the tag and term object + tag = self.get_tag(word, index) + term_obj = self.get_term(word, save_non_seen=False) + + # Skip terms with zero term frequency (not in the original document) + if term_obj.tf == 0: + term_obj = None + + candidate_terms.append((tag, word, term_obj)) + + # Check if the candidate has any valid terms + if not any(term[2] for term in candidate_terms): + # Return an invalid composed word if no valid terms + return ComposedWord(None) + + # Create and return the composed word + return ComposedWord(candidate_terms) + + def build_single_terms_features(self, features=None): + """ + Calculates and updates statistical features for all single terms in the text. + This includes term frequency statistics and other features specified in the + features parameter. Only non-stopword terms are considered for statistics + calculation. + + Args: + features (list, optional): Specific features to calculate + """ + # Filter to valid terms (non-stopwords) + valid_terms = [term for term in self.terms.values() if not term.stopword] + valid_tfs = np.array([x.tf for x in valid_terms]) + + # Skip if no valid terms + if len(valid_tfs) == 0: + return + + # Calculate frequency statistics + avg_tf = valid_tfs.mean() + std_tf = valid_tfs.std() + max_tf = max(x.tf for x in self.terms.values()) + + # Prepare statistics dictionary for updating terms + stats = { + "max_tf": max_tf, + "avg_tf": avg_tf, + "std_tf": std_tf, + "number_of_sentences": self.number_of_sentences, + } + + # Update all terms with the calculated statistics + list(map(lambda x: x.update_h(stats, features=features), self.terms.values())) + + def build_mult_terms_features(self, features=None): + """ + Build features for multi-word terms. + + Updates the features for all valid multi-word candidate terms (n-grams). + Only candidates that pass the validity check will have their features updated. + + Args: + features (list, optional): List of features to build. If None, all available features will be built. + """ + # Update only valid candidates (filter then apply update_h) + list( + map( + lambda x: x.update_h(features=features), + [cand for cand in self.candidates.values() if cand.is_valid()], + ) + ) + + def get_term(self, str_word, save_non_seen=True): + """ + Get or create a term object for a word. + + Handles word normalization, stopword checking, and term object creation. + + Args: + str_word (str): The word to get a term object for + save_non_seen (bool, optional): Whether to save new terms to the collection + + Returns: + SingleWord: Term object representing this word + """ + # Normalize the term (convert to lowercase) + unique_term = str_word.lower() + + # Check if it's a stopword in original form + simples_sto = unique_term in self.stopword_set + + # Handle plural forms by removing trailing 's' + if unique_term.endswith("s") and len(unique_term) > 3: + unique_term = unique_term[:-1] + + # Return existing term if already processed + if unique_term in self.terms: + return self.terms[unique_term] + + # Remove punctuation for further analysis + simples_unique_term = unique_term + for pontuation in self.exclude: + simples_unique_term = simples_unique_term.replace(pontuation, "") + + # Determine if this is a stopword (original form, normalized form, or too short) + isstopword = ( + simples_sto + or unique_term in self.stopword_set + or len(simples_unique_term) < 3 + ) + + # Create the term object + term_id = len(self.terms) + term_obj = SingleWord(unique_term, term_id, self.g) + term_obj.stopword = isstopword + + # Save the term to the collection if requestedComposedWord instance to add or update in the candidates dictionary + if save_non_seen: + self.g.add_node(term_id) + self.terms[unique_term] = term_obj + + return term_obj + + def add_cooccur(self, left_term, right_term): + """ + Add a co-occurrence relationship between two terms. + + Updates the co-occurrence graph by adding or incrementing an edge between + two terms. This information is used to calculate term relatedness and + importance in the text. + + Args: + left_term (SingleWord): Source term in the relationship + right_term (SingleWord): Target term in the relationship + """ + # Check if the edge already exists + if right_term.id not in self.g[left_term.id]: + # Create a new edge with initial weight + self.g.add_edge(left_term.id, right_term.id, tf=0.0) + + # Increment the co-occurrence frequency + self.g[left_term.id][right_term.id]["tf"] += 1.0 + + def add_or_update_composedword(self, cand): + """ + Add or update a composed word in the candidates collection. + + Adds a new candidate composed word (n-gram) to the candidates dictionary + or updates an existing one by incrementing its frequency. This is used to + track potential keyphrases in the text. + + Args: + cand (ComposedWord): ComposedWord instance to add or update in the candidates dictionary + """ + # Check if this candidate already exists + if cand.unique_kw not in self.candidates: + # Add new candidate + self.candidates[cand.unique_kw] = cand + else: + # Update existing candidate with new information + self.candidates[cand.unique_kw].uptade_cand(cand) + + # Increment the frequency counter for this candidate + self.candidates[cand.unique_kw].tf += 1.0 diff --git a/yake/data/single_word.py b/yake/data/single_word.py new file mode 100644 index 00000000..c64e6cce --- /dev/null +++ b/yake/data/single_word.py @@ -0,0 +1,359 @@ +""" +Single word term representation module for YAKE keyword extraction. + +This module contains the SingleWord class which represents individual terms +in a document for keyword extraction. It tracks statistical features like +term frequency, position, and relationships with other terms to calculate +a relevance score for each word. +""" + +import math +import numpy as np + +class SingleWord: + """ + Representation of a single word term in the document. + + This class stores and calculates statistical features for individual terms, + including frequency, position, spread, and relationship metrics. These features + are used to calculate a relevance score that indicates the word's importance + in the document. + + Attributes: + See property accessors below for available attributes. + """ + + def __init__(self, unique, idx, graph): + """ + Initialize a SingleWord term object. + + Args: + unique (str): The unique normalized term this object represents + idx (int): Unique identifier for the term in the document + graph (networkx.DiGraph): Word co-occurrence graph from the document + """ + self.id = idx # Fast access needed as it's used in graph operations + self.g = graph # Fast access needed for network calculations + + self.data = { + # Basic information + "unique_term": unique, + "stopword": False, + "h": 0.0, # Final Score + # Term frequency statistics + "tf": 0.0, # Term frequency + "tf_a": 0.0, # Term Frequency for uppercase words + "tf_n": 0.0, # Term Frequency for proper nouns + # Word characteristic metrics + "wfreq": 0.0, # Word frequency + "wcase": 0.0, # Word case metric + "wrel": 1.0, # Word relevance metric + "wpos": 1.0, # Word position metric + "wspread": 0.0, # Word spread across document + "pl": 0.0, # Probability left + "pr": 0.0, # Probability right + "pagerank": 1.0, # PageRank score + # Ocurrence tracking + "occurs": {}, # Sentence Occurrences + } + + # Forward common dictionary operations to self.data + def __getitem__(self, key): + """ + Access attributes dictionary-style with obj['key']. + + Args: + key (str): The attribute key to access + + Returns: + Any: The value associated with the key + """ + return self.data[key] + + def __setitem__(self, key, value): + """ + Set attributes dictionary-style with obj['key'] = value. + + Args: + key (str): The attribute key to set + value (Any): The value to associate with the key + """ + self.data[key] = value + + def get(self, key, default=None): + """ + Get with default, mimicking dict.get(). + + Args: + key (str): The attribute key to access + default (Any, optional): The default value if key doesn't exist + + Returns: + Any: The value associated with the key or the default value + """ + return self.data.get(key, default) + + # The most commonly used properties remain as explicit accessors for backward compatibility + @property + def unique_term(self): + """Get the unique normalized term this object represents.""" + return self.data["unique_term"] + + @property + def stopword(self): + """Get whether this term is a stopword.""" + return self.data["stopword"] + + @stopword.setter + def stopword(self, value): + """ + Set whether this term is a stopword. + + Args: + value (bool): True if the term is a stopword, False otherwise + """ + self.data["stopword"] = value + + @property + def h(self): + """Get the final relevance score of this term (lower is better).""" + return self.data["h"] + + @h.setter + def h(self, value): + """ + Set the final relevance score of this term. + + Args: + value (float): The new score value + """ + self.data["h"] = value + + @property + def tf(self): + """Get the term frequency (number of occurrences) in the document.""" + return self.data["tf"] + + @tf.setter + def tf(self, value): + """ + Set the term frequency value. + + Args: + value (float): The new term frequency value + """ + self.data["tf"] = value + + @property + def occurs(self): + """Get the dictionary of sentence occurrences for this term.""" + return self.data["occurs"] + + # Everything else uses the generic accessor methods + def get_metric(self, name): + """ + Get the value of any word metric. + + Args: + name (str): The name of the metric to retrieve + + Returns: + float: The value of the requested metric + """ + return self.data.get(name, 0.0) + + def set_metric(self, name, value): + """ + Set the value of any word metric. + + Args: + name (str): The name of the metric to set + value (float): The new value for the metric + """ + self.data[name] = value + + def get_graph_metrics(self): + """ + Calculate all graph-based metrics at once. + + Analyzes the term's connections in the co-occurrence graph to compute + various relationship metrics that measure its contextual importance. + + Returns: + dict: Dictionary containing the calculated graph metrics: + - wdr: Word different right (number of outgoing edges) + - wir: Word importance right (sum of outgoing edge weights) + - pwr: Probability weight right (wdr/wir) + - wdl: Word different left (number of incoming edges) + - wil: Word importance left (sum of incoming edge weights) + - pwl: Probability weight left (wdl/wil) + """ + # Out-edges metrics + wdr = len(self.g.out_edges(self.id)) + wir = sum(d["tf"] for (_, _, d) in self.g.out_edges(self.id, data=True)) + pwr = 0 if wir == 0 else wdr / wir + + # In-edges metrics + wdl = len(self.g.in_edges(self.id)) + wil = sum(d["tf"] for (_, _, d) in self.g.in_edges(self.id, data=True)) + pwl = 0 if wil == 0 else wdl / wil + + return {"wdr": wdr, "wir": wir, "pwr": pwr, "wdl": wdl, "wil": wil, "pwl": pwl} + + def update_h(self, stats, features=None): + """ + Update the word's score based on statistics. + + Calculates all the statistical features that determine the word's + relevance score, using document-level statistics for normalization. + + Args: + stats (dict): Document statistics including: + - max_tf (float): Maximum term frequency in the document + - avg_tf (float): Average term frequency + - std_tf (float): Standard deviation of term frequency + - number_of_sentences (int): Total number of sentences + features (list, optional): Specific features to calculate, or None for all + """ + max_tf = stats["max_tf"] + avg_tf = stats["avg_tf"] + std_tf = stats["std_tf"] + number_of_sentences = stats["number_of_sentences"] + + # Get all graph metrics at once + graph_metrics = self.get_graph_metrics() + + # Update metrics based on features + if features is None or "wrel" in features: + # Calculate relatedness metrics using graph connections + self.data["pl"] = graph_metrics["wdl"] / max_tf + self.data["pr"] = graph_metrics["wdr"] / max_tf + self.data["wrel"] = (0.5 + (graph_metrics["pwl"] * (self.tf / max_tf))) + ( + 0.5 + (graph_metrics["pwr"] * (self.tf / max_tf)) + ) + + if features is None or "wfreq" in features: + # Calculate frequency metric normalized by corpus statistics + self.data["wfreq"] = self.tf / (avg_tf + std_tf) + + if features is None or "wspread" in features: + # Calculate spread as proportion of sentences containing the term + self.data["wspread"] = len(self.occurs) / number_of_sentences + + if features is None or "wcase" in features: + # Calculate case feature from uppercase and proper noun occurrences + self.data["wcase"] = max(self.data["tf_a"], self.data["tf_n"]) / ( + 1.0 + math.log(self.tf) + ) + + if features is None or "wpos" in features: + # Calculate position feature from median position of occurrences + self.data["wpos"] = math.log( + math.log(3.0 + np.median(list(self.occurs.keys()))) + ) + + # Calculate final score + self.data["h"] = (self.data["wpos"] * self.data["wrel"]) / ( + self.data["wcase"] + + (self.data["wfreq"] / self.data["wrel"]) + + (self.data["wspread"] / self.data["wrel"]) + ) + + def add_occur(self, tag, sent_id, pos_sent, pos_text): + """ + Add occurrence information for this term. + + Records where in the document this term appears, tracking sentence ID, + position within sentence, global position in text, and updates term + frequency counters. + + Args: + tag (str): Part-of-speech tag for this occurrence ('a' for acronym, 'n' for proper noun, etc.) + sent_id (int): Sentence ID where the term appears + pos_sent (int): Position within the sentence + pos_text (int): Global position in the entire text + """ + # Create empty list for this sentence if it's the first occurrence + if sent_id not in self.occurs: + self.occurs[sent_id] = [] + + # Record position information for this occurrence + self.occurs[sent_id].append((pos_sent, pos_text)) + self.data["tf"] += 1.0 + + # Update special counters for acronyms and proper nouns + if tag == "a": + self.data["tf_a"] += 1.0 + if tag == "n": + self.data["tf_n"] += 1.0 + + # For backward compatibility, define access to common metrics as properties + @property + def wfreq(self): + """Get the word frequency metric.""" + return self.data["wfreq"] + + @wfreq.setter + def wfreq(self, value): + """Set the word frequency metric.""" + self.data["wfreq"] = value + + @property + def wcase(self): + """Get the word case metric.""" + return self.data["wcase"] + + @wcase.setter + def wcase(self, value): + """Set the word case metric.""" + self.data["wcase"] = value + + @property + def wrel(self): + """Get the word relevance metric.""" + return self.data["wrel"] + + @wrel.setter + def wrel(self, value): + """Set the word relevance metric.""" + self.data["wrel"] = value + + @property + def wpos(self): + """Get the word position metric.""" + return self.data["wpos"] + + @wpos.setter + def wpos(self, value): + """Set the word position metric.""" + self.data["wpos"] = value + + @property + def wspread(self): + """Get the word spread metric.""" + return self.data["wspread"] + + @wspread.setter + def wspread(self, value): + """Set the word spread metric.""" + self.data["wspread"] = value + + @property + def pl(self): + """Get the probability left metric.""" + return self.data["pl"] + + @pl.setter + def pl(self, value): + """Set the probability left metric.""" + self.data["pl"] = value + + @property + def pr(self): + """Get the probability right metric.""" + return self.data["pr"] + + @pr.setter + def pr(self, value): + """Set the probability right metric.""" + self.data["pr"] = value diff --git a/yake/data/utils.py b/yake/data/utils.py new file mode 100644 index 00000000..bcb08379 --- /dev/null +++ b/yake/data/utils.py @@ -0,0 +1,138 @@ +""" +Text processing utility module for YAKE keyword extraction. + +This module provides essential text preprocessing functions for the YAKE algorithm, +including text normalization, sentence segmentation, tokenization, and word +categorization. These utilities form the foundation for clean and consistent +text analysis throughout the keyword extraction pipeline. +""" + +import re +from segtok.segmenter import split_multi +from segtok.tokenizer import web_tokenizer, split_contractions + +# Stopword weighting method for multi-word term scoring: +# - "bi": Use bi-directional weighting (default, considers term connections) +# - "h": Use direct term scores (treat stopwords like normal words) +# - "none": Ignore stopwords completely +STOPWORD_WEIGHT = "bi" + +def pre_filter(text): + """Pre-filter text before processing. + + This function prepares raw text for keyword extraction by normalizing its format. + It performs several transformations: + + 1. Splits the text into parts based on newline characters + 2. Detects if a part starts with a capital letter (potentially a new paragraph) + 3. Adds appropriate spacing between parts: + - Double newlines for parts starting with capital letters (likely new paragraphs) + - Single spaces for other parts (likely continuing text) + 4. Replaces all tab characters with spaces for consistent formatting + + This preprocessing helps maintain paragraph structure while normalizing + whitespace, which improves the accuracy of subsequent text analysis steps + like sentence boundary detection and keyword extraction. + + Args: + text: Raw input text to be pre-filtered + + Returns: + Normalized text with consistent spacing and paragraph structure + """ + # Regular expression to detect lines starting with capital letters + prog = re.compile("^(\\s*([A-Z]))") + + # Split the text into lines + parts = text.split("\n") + buffer = "" + + # Process each line + for part in parts: + # Determine separator: preserve paragraph breaks for lines starting with capital letters + sep = " " + if prog.match(part): + sep = "\n\n" + + # Append the processed line to the buffer, replacing tabs with spaces + buffer += sep + part.replace("\t", " ") + + return buffer + +def tokenize_sentences(text): + """ + Split text into sentences and tokenize into words. + + This function performs two-level tokenization: first dividing the text into + sentences using segtok's sentence segmenter, then tokenizing each sentence + into individual words. It also handles contractions and filters out empty + or invalid tokens. + + Args: + text (str): The input text to be tokenized + + Returns: + list: A nested list structure where each inner list contains the tokens + for a single sentence in the original text + """ + return [ + # Inner list: tokenize each sentence into words + [ + w # Keep only valid word tokens + for w in split_contractions(web_tokenizer(s)) + # Filter out standalone apostrophes and empty tokens + if not (w.startswith("'") and len(w) > 1) and len(w) > 0 + ] + # Outer list: iterate through sentences + for s in list(split_multi(text)) + # Skip empty sentences + if len(s.strip()) > 0 + ] + +def get_tag(word, i, exclude): + """ + Determine the linguistic tag of a word based on its characteristics. + + This function categorizes words into different types based on their + orthographic features (capitalization, digits, special characters). + These tags are used to identify proper nouns, acronyms, numbers, and + unusual token patterns, which affect keyword scoring and filtering. + + Args: + word (str): The word to classify + i (int): Position of the word within its sentence (0 = first word) + exclude (set): Set of characters to consider as punctuation/special chars + + Returns: + str: A single character tag representing the word type: + - "d": Digit or numeric value + - "u": Unusual word (mixed alphanumeric or special characters) + - "a": Acronym (all uppercase) + - "n": Proper noun (capitalized, not at start of sentence) + - "p": Plain word (default) + """ + # Check if word is numeric (with possible commas and a decimal point) + if word.replace(",", "").isdigit() or word.replace(",", "").replace(".", "", 1).isdigit(): + return "d" + + # Count character types for classification + cdigit = sum(c.isdigit() for c in word) + calpha = sum(c.isalpha() for c in word) + cexclude = sum(c in exclude for c in word) + + # Classify unusual tokens: mixed alphanumeric, special chars, or multiple punctuation + if (cdigit > 0 and calpha > 0) or (cdigit == 0 and calpha == 0) or cexclude > 1: + return "u" + + # Identify acronyms (all uppercase words) + if word.isupper() and len(word) > 0: + return "a" + + # Identify proper nouns (capitalized words not at sentence beginning) + if len(word) > 1 and word[0].isupper() and i > 0: + # Check that only the first letter is uppercase (not an all-caps word) + if sum(c.isupper() for c in word) == 1: + return "n" + + # Default case: plain word + return "p" diff --git a/yake/datarepresentation.py b/yake/datarepresentation.py deleted file mode 100644 index d6e9973d..00000000 --- a/yake/datarepresentation.py +++ /dev/null @@ -1,424 +0,0 @@ -from segtok.segmenter import split_multi -from segtok.tokenizer import web_tokenizer, split_contractions - -import networkx as nx -import numpy as np -import string -import os -import math -import jellyfish -import re - -STOPWORD_WEIGHT = 'bi' - -class DataCore(object): - - def __init__(self, text, stopword_set, windowsSize, n, tagsToDiscard = set(['u', 'd']), exclude = set(string.punctuation)): - self.number_of_sentences = 0 - self.number_of_words = 0 - self.terms = {} - self.candidates = {} - self.sentences_obj = [] - self.sentences_str = [] - self.G = nx.DiGraph() - self.exclude = exclude - self.tagsToDiscard = tagsToDiscard - self.freq_ns = {} - for i in range(n): - self.freq_ns[i+1] = 0. - self.stopword_set = stopword_set - self._build(text, windowsSize, n) - - def build_candidate(self, candidate_string): - sentences_str = [w for w in split_contractions(web_tokenizer(candidate_string.lower())) if not (w.startswith("'") and len(w) > 1) and len(w) > 0] - candidate_terms = [] - for (i, word) in enumerate(sentences_str): - tag = self.getTag(word, i) - term_obj = self.getTerm(word, save_non_seen=False) - if term_obj.tf == 0: - term_obj = None - candidate_terms.append( (tag, word, term_obj) ) - if len([cand for cand in candidate_terms if cand[2] != None]) == 0: - invalid_virtual_cand = composed_word(None) - return invalid_virtual_cand - virtual_cand = composed_word(candidate_terms) - return virtual_cand - - # Build the datacore features - def _build(self, text, windowsSize, n): - text = self.pre_filter(text) - self.sentences_str = [ [w for w in split_contractions(web_tokenizer(s)) if not (w.startswith("'") and len(w) > 1) and len(w) > 0] for s in list(split_multi(text)) if len(s.strip()) > 0] - self.number_of_sentences = len(self.sentences_str) - pos_text = 0 - block_of_word_obj = [] - sentence_obj_aux = [] - for (sentence_id, sentence) in enumerate(self.sentences_str): - sentence_obj_aux = [] - block_of_word_obj = [] - for (pos_sent, word) in enumerate(sentence): - if len([c for c in word if c in self.exclude]) == len(word): # If the word is based on exclude chars - if len(block_of_word_obj) > 0: - sentence_obj_aux.append( block_of_word_obj ) - block_of_word_obj = [] - else: - tag = self.getTag(word, pos_sent) - term_obj = self.getTerm(word) - term_obj.addOccur(tag, sentence_id, pos_sent, pos_text) - pos_text += 1 - - #Create co-occurrence matrix - if tag not in self.tagsToDiscard: - word_windows = list(range( max(0, len(block_of_word_obj)-windowsSize), len(block_of_word_obj) )) - for w in word_windows: - if block_of_word_obj[w][0] not in self.tagsToDiscard: - self.addCooccur(block_of_word_obj[w][2], term_obj) - #Generate candidate keyphrase list - candidate = [ (tag, word, term_obj) ] - cand = composed_word(candidate) - self.addOrUpdateComposedWord(cand) - word_windows = list(range( max(0, len(block_of_word_obj)-(n-1)), len(block_of_word_obj) ))[::-1] - for w in word_windows: - candidate.append(block_of_word_obj[w]) - self.freq_ns[len(candidate)] += 1. - cand = composed_word(candidate[::-1]) - self.addOrUpdateComposedWord(cand) - - # Add term to the block of words' buffer - block_of_word_obj.append( (tag, word, term_obj) ) - - if len(block_of_word_obj) > 0: - sentence_obj_aux.append( block_of_word_obj ) - - if len(sentence_obj_aux) > 0: - self.sentences_obj.append(sentence_obj_aux) - - if len(block_of_word_obj) > 0: - sentence_obj_aux.append( block_of_word_obj ) - - if len(sentence_obj_aux) > 0: - self.sentences_obj.append(sentence_obj_aux) - - self.number_of_words = pos_text - - def build_single_terms_features(self, features=None): - validTerms = [ term for term in self.terms.values() if not term.stopword ] - validTFs = (np.array([ x.tf for x in validTerms ])) - - if len(validTFs) == 0: - return - - avgTF = validTFs.mean() - stdTF = validTFs.std() - maxTF = max([ x.tf for x in self.terms.values()]) - list(map(lambda x: x.updateH(maxTF=maxTF, avgTF=avgTF, stdTF=stdTF, number_of_sentences=self.number_of_sentences, features=features), self.terms.values())) - - def build_mult_terms_features(self, features=None): - list(map(lambda x: x.updateH(features=features), [cand for cand in self.candidates.values() if cand.isValid()])) - - def pre_filter(self, text): - prog = re.compile("^(\\s*([A-Z]))") - parts = text.split('\n') - buffer = '' - for part in parts: - sep = ' ' - if prog.match(part): - sep = '\n\n' - buffer += sep + part.replace('\t',' ') - return buffer - - def getTag(self, word, i): - try: - w2 = word.replace(",","") - float(w2) - return "d" - except: - cdigit = len([c for c in word if c.isdigit()]) - calpha = len([c for c in word if c.isalpha()]) - if ( cdigit > 0 and calpha > 0 ) or (cdigit == 0 and calpha == 0) or len([c for c in word if c in self.exclude]) > 1: - return "u" - if len(word) == len([c for c in word if c.isupper()]): - return "a" - if len([c for c in word if c.isupper()]) == 1 and len(word) > 1 and word[0].isupper() and i > 0: - return "n" - return "p" - - def getTerm(self, str_word, save_non_seen=True): - unique_term = str_word.lower() - simples_sto = unique_term in self.stopword_set - if unique_term.endswith('s') and len(unique_term) > 3: - unique_term = unique_term[:-1] - - if unique_term in self.terms: - return self.terms[unique_term] - - # Include this part - simples_unique_term = unique_term - for pontuation in self.exclude: - simples_unique_term = simples_unique_term.replace(pontuation, '') - # until here - isstopword = simples_sto or unique_term in self.stopword_set or len(simples_unique_term) < 3 - - term_id = len(self.terms) - term_obj = single_word(unique_term, term_id, self.G) - term_obj.stopword = isstopword - - if save_non_seen: - self.G.add_node(term_id) - self.terms[unique_term] = term_obj - - return term_obj - - def addCooccur(self, left_term, right_term): - if right_term.id not in self.G[left_term.id]: - self.G.add_edge(left_term.id, right_term.id, TF=0.) - self.G[left_term.id][right_term.id]["TF"]+=1. - - def addOrUpdateComposedWord(self, cand): - if cand.unique_kw not in self.candidates: - self.candidates[cand.unique_kw] = cand - else: - self.candidates[cand.unique_kw].uptadeCand(cand) - self.candidates[cand.unique_kw].tf += 1. - - -class composed_word(object): - def __init__(self, terms): # [ (tag, word, term_obj) ] - if terms == None: - self.start_or_end_stopwords = True - self.tags = set() - return - self.tags = set([''.join([ w[0] for w in terms ])]) - self.kw = ' '.join( [ w[1] for w in terms ] ) - self.unique_kw = self.kw.lower() - self.size = len(terms) - self.terms = [ w[2] for w in terms if w[2] != None ] - self.tf = 0. - self.integrity = 1. - self.H = 1. - self.start_or_end_stopwords = self.terms[0].stopword or self.terms[-1].stopword - - def uptadeCand(self, cand): - for tag in cand.tags: - self.tags.add( tag ) - - def isValid(self): - isValid = False - for tag in self.tags: - isValid = isValid or ( "u" not in tag and "d" not in tag ) - return isValid and not self.start_or_end_stopwords - - def get_composed_feature(self, feature_name, discart_stopword=True): - list_of_features = [ getattr(term, feature_name) for term in self.terms if ( discart_stopword and not term.stopword ) or not discart_stopword ] - sum_f = sum(list_of_features) - prod_f = np.prod(list_of_features) - return ( sum_f, prod_f, prod_f /(sum_f + 1) ) - - def build_features(self, doc_id=None, keys=None, rel=True, rel_approx=True, isVirtual=False, features=['WFreq', 'WRel', 'tf', 'WCase', 'WPos', 'WSpread'], _stopword=[True, False]): - columns = [] - seen = set() - features_cand = [] - - if doc_id != None: - columns.append('doc_id') - features_cand.append(doc_id) - - if keys != None: - if rel: - columns.append('rel') - if self.unique_kw in keys or isVirtual: - features_cand.append(1) - seen.add(self.unique_kw) - else: - features_cand.append(0) - - if rel_approx: - columns.append('rel_approx') - max_gold_ = ('', 0.) - for gold_key in keys: - dist = 1.-jellyfish.levenshtein_distance(gold_key, self.unique_kw ) / max(len(gold_key), len(self.unique_kw)) # _tL - if max_gold_[1] < dist: - max_gold_ = ( gold_key, dist ) - features_cand.append(max_gold_[1]) - - columns.append('kw') - features_cand.append(self.unique_kw) - columns.append('h') - features_cand.append(self.H) - columns.append('tf') - features_cand.append(self.tf) - columns.append('size') - features_cand.append(self.size) - columns.append('isVirtual') - features_cand.append(int(isVirtual)) - - for feature_name in features: - - for discart_stopword in _stopword: - (f_sum, f_prod, f_sum_prod) = self.get_composed_feature(feature_name, discart_stopword=discart_stopword) - columns.append('%ss_sum_K%s' % ('n' if discart_stopword else '', feature_name) ) - features_cand.append(f_sum) - - columns.append('%ss_prod_K%s' % ('n' if discart_stopword else '', feature_name) ) - features_cand.append(f_prod) - - columns.append('%ss_sum_prod_K%s' % ('n' if discart_stopword else '', feature_name) ) - features_cand.append(f_sum_prod) - - return (features_cand, columns, seen) - - def updateH(self, features=None, isVirtual=False): - sum_H = 0. - prod_H = 1. - - for (t, term_base) in enumerate(self.terms): - if not term_base.stopword: - sum_H += term_base.H - prod_H *= term_base.H - - else: - if STOPWORD_WEIGHT == 'bi': - prob_t1 = 0. - if term_base.G.has_edge(self.terms[t-1].id, self.terms[ t ].id): - prob_t1 = term_base.G[self.terms[t-1].id][self.terms[ t ].id]["TF"] / self.terms[t-1].tf - - prob_t2 = 0. - if term_base.G.has_edge(self.terms[ t ].id, self.terms[t+1].id): - prob_t2 = term_base.G[self.terms[ t ].id][self.terms[t+1].id]["TF"] / self.terms[t+1].tf - - prob = prob_t1 * prob_t2 - prod_H *= (1 + (1 - prob ) ) - sum_H -= (1 - prob) - elif STOPWORD_WEIGHT == 'h': - sum_H += term_base.H - prod_H *= term_base.H - elif STOPWORD_WEIGHT == 'none': - pass - - tf_used = 1. - if features == None or "KPF" in features: - tf_used = self.tf - - if isVirtual: - tf_used = np.mean( [term_obj.tf for term_obj in self.terms] ) - - self.H = prod_H / ( ( sum_H + 1 ) * tf_used ) - - def updateH_old(self, features=None, isVirtual=False): - sum_H = 0. - prod_H = 1. - - for (t, term_base) in enumerate(self.terms): - if isVirtual and term_base.tf==0: - continue - - if term_base.stopword: - prob_t1 = 0. - if term_base.G.has_edge(self.terms[t-1].id, self.terms[ t ].id): - prob_t1 = term_base.G[self.terms[t-1].id][self.terms[ t ].id]["TF"] / self.terms[t-1].tf - - prob_t2 = 0. - if term_base.G.has_edge(self.terms[ t ].id, self.terms[t+1].id): - prob_t2 = term_base.G[self.terms[ t ].id][self.terms[t+1].id]["TF"] / self.terms[t+1].tf - - prob = prob_t1 * prob_t2 - prod_H *= (1 + (1 - prob ) ) - sum_H -= (1 - prob) - else: - sum_H += term_base.H - prod_H *= term_base.H - tf_used = 1. - if features == None or "KPF" in features: - tf_used = self.tf - if isVirtual: - tf_used = np.mean( [term_obj.tf for term_obj in self.terms] ) - self.H = prod_H / ( ( sum_H + 1 ) * tf_used ) - - -class single_word(object): - - def __init__(self, unique, idx, graph): - self.unique_term = unique - self.id = idx - self.tf = 0. - self.WFreq = 0.0 - self.WCase = 0.0 - self.tf_a = 0. - self.tf_n = 0. - self.WRel = 1.0 - self.PL = 0. - self.PR = 0. - self.occurs = {} - self.WPos = 1.0 - self.WSpread = 0.0 - self.H = 0.0 - self.stopword = False - self.G = graph - - self.pagerank = 1. - - def updateH(self, maxTF, avgTF, stdTF, number_of_sentences, features=None): - """if features == None or "WRel" in features: - self.PL = self.WDL / maxTF - self.PR = self.WDR / maxTF - self.WRel = ( (0.5 + (self.PWL * (self.tf / maxTF) + self.PL)) + (0.5 + (self.PWR * (self.tf / maxTF) + self.PR)) )""" - - if features == None or "WRel" in features: - self.PL = self.WDL / maxTF - self.PR = self.WDR / maxTF - self.WRel = ( (0.5 + (self.PWL * (self.tf / maxTF))) + (0.5 + (self.PWR * (self.tf / maxTF))) ) - - if features == None or "WFreq" in features: - self.WFreq = self.tf / (avgTF + stdTF) - - if features == None or "WSpread" in features: - self.WSpread = len(self.occurs) / number_of_sentences - - if features == None or "WCase" in features: - self.WCase = max(self.tf_a, self.tf_n) / (1. + math.log(self.tf)) - - if features == None or "WPos" in features: - self.WPos = math.log( math.log( 3. + np.median(list(self.occurs.keys())) ) ) - - self.H = (self.WPos * self.WRel) / (self.WCase + (self.WFreq / self.WRel) + (self.WSpread / self.WRel)) - - @property - def WDR(self): - return len( self.G.out_edges(self.id) ) - - @property - def WIR(self): - return sum( [ d['TF'] for (u,v,d) in self.G.out_edges(self.id, data=True) ] ) - - @property - def PWR(self): - wir = self.WIR - if wir == 0: - return 0 - return self.WDR / wir - - @property - def WDL(self): - return len( self.G.in_edges(self.id) ) - - @property - def WIL(self): - return sum( [ d['TF'] for (u,v,d) in self.G.in_edges(self.id, data=True) ] ) - - @property - def PWL(self): - wil = self.WIL - if wil == 0: - return 0 - return self.WDL / wil - - def addOccur(self, tag, sent_id, pos_sent, pos_text): - if sent_id not in self.occurs: - self.occurs[sent_id] = [] - - self.occurs[sent_id].append( (pos_sent, pos_text) ) - self.tf += 1. - - if tag == "a": - self.tf_a += 1. - if tag == "n": - self.tf_n += 1. diff --git a/yake/highlight.py b/yake/highlight.py deleted file mode 100644 index 3712907a..00000000 --- a/yake/highlight.py +++ /dev/null @@ -1,150 +0,0 @@ -import re - -DEFAULT_HIGHLIGHT_PRE = "" -DEFAULT_HIGHLIGHT_POST = "" - -class TextHighlighter(object): - - def __init__(self, max_ngram_size, highlight_pre = DEFAULT_HIGHLIGHT_PRE, highlight_post = DEFAULT_HIGHLIGHT_POST): - """ - TextHighlighter constructor. Define highlight text snippets - - :max_ngram_size - Specifies the maximum ngram size in the keywords. - :highlight_pre – Specifies the text that should appear before a highlighted term.(e.g. ). It defaults to - :highlight_post – Specifies the text that should appear after a highlighted term. (e.g. ). It defaults to - """ - - self.highlight_pre = highlight_pre - self.highlight_post = highlight_post - self.max_ngram_size = max_ngram_size - - def highlight(self, text, keywords): - """ - Returns the highlighted text snippets of matching text in the original data - """ - - n_text = '' - # extract only the kw - if(len(keywords) > 0): - kw_list = keywords - - if(type(keywords[0]) == tuple): - kw_list = [x[0] for x in keywords] - - text = text.strip() - if self.max_ngram_size == 1: - n_text = self.format_one_gram_text(text, kw_list) - elif self.max_ngram_size > 1: - n_text = self.format_n_gram_text(text, kw_list, self.max_ngram_size) - - return n_text - - def format_one_gram_text(self, text, relevant_words_array): - text_tokens = text.replace('\n',' ').split(' ') - relevant_words_array = [kw.lower() for kw in relevant_words_array] - try: - for tk in range(len(text_tokens)): - kw = re.sub('[!",:.;?()]$|^[!",:.;?()]|\W["!,:.;?()]', '', text_tokens[tk]) - if kw.lower() in relevant_words_array: - text_tokens[tk] = text_tokens[tk].replace(kw, self.highlight_pre + kw + self.highlight_post) - except: - pass - new_text = ' '.join(text_tokens) - return new_text - - def format_n_gram_text(self, text, relevant_words_array, n_gram): - text_tokens = text.replace('\n',' ').split(' ') - relevant_words_array = [kw.lower() for kw in relevant_words_array] - - y = 0 - final_splited_text = [] - while y < len(text_tokens): - - splited_n_gram_kw_list = [] - n_gram_kw_list = [] - n_gram_word_list, splited_n_gram_kw_list = self.find_more_relevant(y, text_tokens, n_gram, relevant_words_array, n_gram_kw_list, splited_n_gram_kw_list) - if n_gram_word_list: - - if len(n_gram_word_list[0].split(' ')) == 1: - y, new_expression = self.replace_token(text_tokens, y, n_gram_word_list) - final_splited_text.append(new_expression) - else: - kw_list = [] - splited_n_gram_kw_list = [] - splited_one = n_gram_word_list[0].split() - - for len_kw in range(0, len(splited_one)): - kw_list, splited_n_gram_kw_list = self.find_more_relevant(y+len_kw, text_tokens, n_gram, relevant_words_array, kw_list, splited_n_gram_kw_list) - min_score_word = min(kw_list, key=lambda x: relevant_words_array.index(x.lower())) - - if kw_list.index(min_score_word) == 0: - term_list = [min_score_word] - y, new_expression = self.replace_token(text_tokens, y, term_list) - final_splited_text.append(new_expression) - - elif kw_list.index(min_score_word) >= 1: - index_of_more_relevant = splited_n_gram_kw_list[0].index(min_score_word.split()[0]) - temporal_kw = ' '.join(splited_n_gram_kw_list[0][:index_of_more_relevant]) - if temporal_kw in relevant_words_array: - try: - if relevant_words_array.index(temporal_kw) > relevant_words_array.index(final_splited_text[-1] +' '+temporal_kw) and not re.findall(self.highlight_pre, final_splited_text[-1]): - term_list = [final_splited_text[-1] +' '+temporal_kw] - del final_splited_text[-1] - y -= 1 - y, new_expression = self.replace_token(text_tokens, y, term_list) - final_splited_text.append(new_expression) - else: - term_list = [temporal_kw] - y, new_expression = self.replace_token(text_tokens, y, term_list) - final_splited_text.append(new_expression) - except: - term_list = [temporal_kw] - y, new_expression = self.replace_token(text_tokens, y, term_list) - final_splited_text.append(new_expression) - - else: - for tmp_kw in splited_n_gram_kw_list[0][:index_of_more_relevant]: - if tmp_kw in relevant_words_array: - term_list = [tmp_kw] - y, new_expression = self.replace_token(text_tokens, y, term_list) - final_splited_text.append(new_expression) - else: - final_splited_text.append(text_tokens[y]) - y += 1 - - else: - final_splited_text.append(text_tokens[y]) - y += 1 - new_text = ' '.join(final_splited_text) - - return new_text - - - def find_more_relevant(self, y, text_tokens, n_gram, relevant_words_array, kw_list, splited_n_gram_word_list): - temporary_list = [] - temporary_list_two = [] - for i in range(n_gram): - - temporary_list.append(text_tokens[y:y + i + 1]) - k = re.sub('''[!",:.;?()]$|^[!",':.;?()]|\W["!,:.;?()]''', '', ' '.join(temporary_list[i])) - - if k.lower() in relevant_words_array: - temporary_list_two.append(k) - - n_gram_word_list = sorted(temporary_list_two, key=lambda x: relevant_words_array.index(x.lower())) - - try: - kw_list.append(n_gram_word_list[0]) - splited_n_gram_word_list.append(n_gram_word_list[0].split()) - except: - pass - - return kw_list, splited_n_gram_word_list - - - def replace_token(self, text_tokens, y, n_gram_word_list): - txt = ' '.join(text_tokens[y:y + len(n_gram_word_list[0].split(' '))]) - - new_expression = txt.replace(re.sub('[!",:.;?()]$|^[!",:.;?()]|\W["!,:.;?()]', '', txt), self.highlight_pre + n_gram_word_list[0] + self.highlight_post) - y += len(n_gram_word_list[0].split(' ')) - return y, new_expression \ No newline at end of file diff --git a/yake/yake.py b/yake/yake.py deleted file mode 100644 index 6ec7f59b..00000000 --- a/yake/yake.py +++ /dev/null @@ -1,88 +0,0 @@ -# -*- coding: utf-8 -*- - -"""Main module.""" - -import string -import os -import jellyfish -from .Levenshtein import Levenshtein - -from .datarepresentation import DataCore - -class KeywordExtractor(object): - - def __init__(self, lan="en", n=3, dedupLim=0.9, dedupFunc='seqm', windowsSize=1, top=20, features=None, stopwords=None): - self.lan = lan - - dir_path = os.path.dirname(os.path.realpath(__file__)) - - local_path = os.path.join("StopwordsList", "stopwords_%s.txt" % lan[:2].lower()) - - if os.path.exists(os.path.join(dir_path,local_path)) == False: - local_path = os.path.join("StopwordsList", "stopwords_noLang.txt") - - resource_path = os.path.join(dir_path,local_path) - - if stopwords is None: - try: - with open(resource_path, encoding='utf-8') as stop_fil: - self.stopword_set = set( stop_fil.read().lower().split("\n") ) - except: - print('Warning, read stopword list as ISO-8859-1') - with open(resource_path, encoding='ISO-8859-1') as stop_fil: - self.stopword_set = set( stop_fil.read().lower().split("\n") ) - else: - self.stopword_set = set(stopwords) - - self.n = n - self.top = top - self.dedupLim = dedupLim - self.features = features - self.windowsSize = windowsSize - if dedupFunc == 'jaro_winkler' or dedupFunc == 'jaro': - self.dedu_function = self.jaro - elif dedupFunc.lower() == 'sequencematcher' or dedupFunc.lower() == 'seqm': - self.dedu_function = self.seqm - else: - self.dedu_function = self.levs - - def jaro(self, cand1, cand2): - return jellyfish.jaro_winkler(cand1, cand2 ) - - def levs(self, cand1, cand2): - return 1.-jellyfish.levenshtein_distance(cand1, cand2 ) / max(len(cand1),len(cand2)) - - def seqm(self, cand1, cand2): - return Levenshtein.ratio(cand1, cand2) - - def extract_keywords(self, text): - try: - if not(len(text) > 0): - return [] - - text = text.replace('\n\t',' ') - dc = DataCore(text=text, stopword_set=self.stopword_set, windowsSize=self.windowsSize, n=self.n) - dc.build_single_terms_features(features=self.features) - dc.build_mult_terms_features(features=self.features) - resultSet = [] - todedup = sorted([cc for cc in dc.candidates.values() if cc.isValid()], key=lambda c: c.H) - - if self.dedupLim >= 1.: - return ([ (cand.unique_kw, cand.H) for cand in todedup])[:self.top] - - for cand in todedup: - toadd = True - for (h, candResult) in resultSet: - dist = self.dedu_function(cand.unique_kw, candResult.unique_kw) - if dist > self.dedupLim: - toadd = False - break - if toadd: - resultSet.append( (cand.H, cand) ) - if len(resultSet) == self.top: - break - - return [ (cand.kw,h) for (h,cand) in resultSet] - except Exception as e: - print(f"Warning! Exception: {e} generated by the following text: '{text}' ") - return []