diff --git a/.github/workflows/pythonpublish.yml b/.github/workflows/pythonpublish.yml index 80beec3..97d990c 100644 --- a/.github/workflows/pythonpublish.yml +++ b/.github/workflows/pythonpublish.yml @@ -21,23 +21,18 @@ jobs: uses: actions/setup-python@v5 with: python-version: '3.x' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install setuptools wheel twine + - name: Install uv + uses: astral-sh/setup-uv@v5 - name: Make sure unit tests succeed run: | git config --global user.name "Github Action" git config --global user.email "githubaction@gmail.com" - pip install -r requirements_dev.txt - pip install . - pytest + uv run pytest - name: Build run: | - pip install build setuptools - python -m build + uv build # See https://docs.pypi.org/trusted-publishers/using-a-publisher/ - name: Publish package distributions to PyPI @@ -45,5 +40,4 @@ jobs: - name: Deploy mkdocs site run: | - pip install -r requirements_dev.txt - mkdocs gh-deploy --force + uv run mkdocs gh-deploy --force diff --git a/.github/workflows/scheduled_unittests.yml b/.github/workflows/scheduled_unittests.yml index 58dd70c..0737445 100644 --- a/.github/workflows/scheduled_unittests.yml +++ b/.github/workflows/scheduled_unittests.yml @@ -16,23 +16,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@master - - - name: Setup Python - uses: actions/setup-python@master - with: - python-version: "3.12" - - - name: Install dependencies - run: | - pip3 install --upgrade pip - pip3 install --upgrade setuptools - pip3 install --upgrade wheel - pip3 install -r requirements_dev.txt - pip3 install . - + - name: Install uv and set the python version + uses: astral-sh/setup-uv@v5 - name: Run unit tests run: | git config --global user.name "Github Action" git config --global user.email "githubaction@gmail.com" - pytest + uv run pytest \ No newline at end of file diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml index 6d0d68c..0eacc2d 100644 --- a/.github/workflows/unittests.yml +++ b/.github/workflows/unittests.yml @@ -2,7 +2,7 @@ name: Unit tests on: [pull_request] jobs: run: - name: Run unit tests with codecov upload + name: Run unit tests runs-on: ${{ matrix.os }} env: USING_COVERAGE: '3.10' @@ -13,22 +13,14 @@ jobs: steps: - uses: actions/checkout@master - - name: Setup Python - uses: actions/setup-python@master + - name: Install uv and set the python version + uses: astral-sh/setup-uv@v5 with: python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - pip3 install --upgrade pip - pip3 install --upgrade setuptools - pip3 install --upgrade wheel - pip3 install -r requirements_dev.txt - pip3 install . - - name: Run unit tests run: | git config --global user.name "Github Action" git config --global user.email "githubaction@gmail.com" - pytest --cov=mkdocs_git_revision_date_localized_plugin --cov-report=xml - \ No newline at end of file + uv run pytest --cov=mkdocs_git_revision_date_localized_plugin --cov-report=xml + diff --git a/.github/workflows/unittests_codecov.yml b/.github/workflows/unittests_codecov.yml index 63904b4..b8cfab3 100644 --- a/.github/workflows/unittests_codecov.yml +++ b/.github/workflows/unittests_codecov.yml @@ -21,24 +21,16 @@ jobs: steps: - uses: actions/checkout@master - - name: Setup Python - uses: actions/setup-python@master + - name: Install uv and set the python version + uses: astral-sh/setup-uv@v5 with: python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - pip3 install --upgrade pip - pip3 install --upgrade setuptools - pip3 install --upgrade wheel - pip install -r requirements_dev.txt - pip3 install . - - name: Generate coverage report run: | git config --global user.name "Github Action" git config --global user.email "githubaction@gmail.com" - pytest --cov=mkdocs_git_revision_date_localized_plugin --cov-report=xml + uv run pytest --cov=mkdocs_git_revision_date_localized_plugin --cov-report=xml - name: Upload coverage to Codecov if: "contains(env.USING_COVERAGE, matrix.python-version)" diff --git a/.gitignore b/.gitignore index 3f960da..7b91b20 100644 --- a/.gitignore +++ b/.gitignore @@ -157,8 +157,6 @@ coverage.xml docs/_build/ # PyBuilder target/ -# pyenv -.python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..e4fba21 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f10cde8..b1b9d30 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,14 +7,16 @@ Thanks for considering to contribute to this project! Some guidelines: - This package tries to be as simple as possible for the user (hide any complexity from the user). New options are only added when there is clear value to the majority of users. - When issues or pull requests are not going to be resolved or merged, they should be closed as soon as possible. This is kinder than deciding this after a long period. Our issue tracker should reflect work to be done. +## Setup + +We use [uv to manage dependencies](https://docs.astral.sh/uv/getting-started/installation/). + ## Unit Tests -Make sure to install an editable version before running the tests: +To run the unit tests, use: ```python -pip install -r requirement_dev.txt -pip install -e . -pytest --cov=mkdocs_git_revision_date_localized_plugin --cov-report term-missing tests/ +uv run pytest --cov=mkdocs_git_revision_date_localized_plugin --cov-report term-missing tests/ ``` If it makes sense, writing tests for your PRs is always appreciated and will help get them merged. @@ -25,9 +27,7 @@ To quickly serve a test website with your latest changes to the plugin use the s For example: ```python -pip install -r tests/test_requirements.txt -pip install -e . -mkdocs serve -f tests/fixtures/basic_project/mkdocs.yml +uv run mkdocs serve -f tests/fixtures/basic_project/mkdocs.yml ``` ## Code Style @@ -35,4 +35,6 @@ mkdocs serve -f tests/fixtures/basic_project/mkdocs.yml Make sure your code *roughly* follows [PEP-8](https://www.python.org/dev/peps/pep-0008/) and keeps things consistent with the rest of the code. +We run `ruff format` to automatically style the code. + We use Google-style docstrings. diff --git a/MANIFEST.in b/MANIFEST.in index c84efdc..1a03abb 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,3 +1,2 @@ -include requirements.txt include mkdocs_git_revision_date_localized_plugin/js/*.js include mkdocs_git_revision_date_localized_plugin/css/*.css diff --git a/README.md b/README.md index 624b9bf..966a547 100644 --- a/README.md +++ b/README.md @@ -7,17 +7,12 @@ # mkdocs-git-revision-date-localized-plugin -[MkDocs](https://www.mkdocs.org/) plugin that enables displaying the date of the last git modification of a page. The plugin uses [babel](https://github.com/python-babel/babel/tree/master/babel) and [timeago.js](https://github.com/hustcc/timeago.js) to provide different localized date formats. Initial fork from [mkdocs-git-revision-date-plugin](https://github.com/zhaoterryy/mkdocs-git-revision-date-plugin). +[MkDocs](https://www.mkdocs.org/) plugin that enables displaying the date of the last git modification of a page. The plugin uses [babel](https://github.com/python-babel/babel/tree/master/babel) and [timeago.js](https://github.com/hustcc/timeago.js) to provide different localized date formats. Works with [`mkdocs-material`](https://squidfunk.github.io/mkdocs-material/), see [adding a git repository](https://squidfunk.github.io/mkdocs-material/setup/adding-a-git-repository/). ![demo](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/raw/master/demo_screencast.gif) (*Example when used together with the [mkdocs-material](https://github.com/squidfunk/mkdocs-material) theme*) -Other MkDocs plugins that use information from git: - -- [mkdocs-git-authors-plugin](https://github.com/timvink/mkdocs-git-authors-plugin) for displaying the authors from git -- [mkdocs-git-committers-plugin](https://github.com/byrnereese/mkdocs-git-committers-plugin) for displaying authors' github user profiles - ## Setup Install the plugin using `pip3` with the following command: @@ -49,6 +44,18 @@ This plugin needs access to the last commit that touched a specific file to be a - Bitbucket pipelines: set `clone: depth: full` (docs) - Azure Devops pipelines: set `Agent.Source.Git.ShallowFetchDepth` to something very high like `10e99` ([docs](https://docs.microsoft.com/en-us/azure/devops/pipelines/repos/pipeline-options-for-git?view=azure-devops#shallow-fetch)) +*Tip*: You can speed up your builds for large codebases by running git garbage collection (`git gc`) occasionly. You can also use _sparse checkouts_ to only apply the fetch-depth 0 for the folders we're interested (credits Martin [in this tweet](https://x.com/squidfunk/status/1705279829770150291)): + +```yaml +# example sparse checkout for github actions +- uses: actions/checkout@v4 + with: + fetch-depth: 0 + sparse-checkout: | + docs + includes +``` + ## Documentation See [timvink.github.io/mkdocs-git-revision-date-localized-plugin](https://timvink.github.io/mkdocs-git-revision-date-localized-plugin/index.html). @@ -56,3 +63,10 @@ See [timvink.github.io/mkdocs-git-revision-date-localized-plugin](https://timvin ## Contributing Contributions are very welcome! Please read [CONTRIBUTING.md](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/blob/master/CONTRIBUTING.md) before putting in any work. + +## Related MkDocs plugins: + +- [mkdocs-git-authors-plugin](https://github.com/timvink/mkdocs-git-authors-plugin) for displaying the authors from git +- [mkdocs-git-committers-plugin-2](https://github.com/ojacques/mkdocs-git-committers-plugin-2) for displaying authors' github user profiles +- [mkdocs-document-dates](https://github.com/jaywhj/mkdocs-document-dates) for displaying dates based on file creation and modification dates. +- Initial fork from [mkdocs-git-revision-date-plugin](https://github.com/zhaoterryy/mkdocs-git-revision-date-plugin). \ No newline at end of file diff --git a/docs/available-variables.md b/docs/available-variables.md index b23c42b..04eeb0e 100644 --- a/docs/available-variables.md +++ b/docs/available-variables.md @@ -1,8 +1,8 @@ # Available variables -This plugin offers the following variables: +This plugin offers the following timestamp variables: -| timestamp | description | +| variable | description | |:-----------|:------------| | `git_revision_date_localized` | Last git commit that touched a file. Enabled by default. | | `git_creation_date_localized` | First git commit that touched a file. Enable in [options](options.md). | @@ -33,6 +33,9 @@ To allow for more flexibility when overriding a theme there are also variables f - `page.meta.git_revision_date_localized_raw_iso_datetime` - `page.meta.git_revision_date_localized_raw_timeago` - `page.meta.git_revision_date_localized_raw_custom` + +Their are also available on the entire site level: + - `page.meta.git_site_revision_date_localized_raw_datetime` - `page.meta.git_site_revision_date_localized_raw_iso_date` - `page.meta.git_site_revision_date_localized_raw_date` @@ -49,6 +52,15 @@ And if you've enabled creation date in the config: - `page.meta.git_creation_date_localized_raw_timeago` - `page.meta.git_creation_date_localized_raw_custom` +We also expose the git hash and the git tag (empty if not tag associated with the commit): + +- `page.meta.git_revision_date_localized_hash` +- `page.meta.git_revision_date_localized_tag` +- `page.meta.git_site_revision_date_localized_hash` +- `page.meta.git_site_revision_date_localized_tag` +- `page.meta.git_creation_date_localized_hash` +- `page.meta.git_creation_date_localized_tag` + !!! warning "timeago.js dependency" The `*_timeago` variables require the [timeago.js](https://timeago.org/) dependency. This is automatically injected when the [option](options.md) `type: timeago` is set. Alternatively, you can add [timeago.js](https://timeago.org/) using the [`extra_javascript`](https://www.mkdocs.org/user-guide/configuration/#extra_javascript) option of MkDocs: diff --git a/docs/howto/specify-locale.md b/docs/howto/specify-locale.md index cfeb46d..1123898 100644 --- a/docs/howto/specify-locale.md +++ b/docs/howto/specify-locale.md @@ -1,6 +1,6 @@ # Specify a locale -`locale` is a two letter [ISO639](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) language code that `git-revision-date-localized` uses to display dates in your preferred language. +`locale` is aa two letter [ISO639](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) language code (f.e. `en`) or [5-letter language code with added territory/region/country](https://www.mkdocs.org/user-guide/localizing-your-theme/#supported-locales) (`en_US`) that `git-revision-date-localized` uses to display dates in your preferred language. For example: @@ -68,6 +68,7 @@ plugins: If no `locale` is specified anywhere, the fallback is English with the US date format (`en`). !!! info "Supported locales" + - When used in combination with `type: date` or `type: datetime`, translation is done using [babel](https://github.com/python-babel/babel) which supports [these locales](http://www.unicode.org/cldr/charts/latest/supplemental/territory_language_information.html) - When used in combination with `type: timeago` then [timeago.js](https://github.com/hustcc/timeago.js) is added to your website, which supports [these locales](https://github.com/hustcc/timeago.js/tree/master/src/lang). If you specify a locale not supported by timeago.js, the fallback is English (`en`) diff --git a/docs/options.md b/docs/options.md index 1c24090..613753a 100644 --- a/docs/options.md +++ b/docs/options.md @@ -18,6 +18,7 @@ You can customize the plugin by setting options in `mkdocs.yml`. For example: enable_git_follow: true enabled: true strict: true + ignored_commits_file: .git-blame-ignore-revs ``` ## `type` @@ -52,17 +53,19 @@ Default is `UTC`. Specify a time zone database name ([reference](https://en.wiki ## `locale` -Default is `None`. Specify a two letter [ISO639](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) language code to display dates in your preferred language. Note this plugin supports many different ways to [specify the locale](howto/specify-locale.md), but if not specified anywhere the fallback is English (`en`). +Default is `None`. Specify a two letter [ISO639](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) language code (f.e. `en`) or [5-letter language code with added territory/region/country](https://www.mkdocs.org/user-guide/localizing-your-theme/#supported-locales) (`en_US`) to display dates in your preferred language. Note this plugin supports many different ways to [specify the locale](howto/specify-locale.md), but if not specified _anywhere_ the fallback will be English (`en`). `locale` is used to translate timestamps to dates when `type: date` or `type: datetime` (using [babel](https://github.com/python-babel/babel)) as well as to translate datetimes to a relative timeago string when `type: timeago` (using [timeago.js](https://github.com/hustcc/timeago.js)). Example outputs: ```yaml -April 27, 2021 # `locale: en` with `type: date` (default) -April 27, 2021 13:11:28 # `locale: en` with `type: datetime` -2 weeks ago # `locale: en` with `type: timeago` -27 de marzo de 2021 # `locale: es` with `type: date` -27 de marzo de 2021 13:57:28 # `locale: es` with `type: datetime` -hace 2 semanas # `locale: es` with `type: timeago` +# `locale: en` +April 27, 2021 # with `type: date` (default) +April 27, 2021 13:11:28 # with `type: datetime` +2 weeks ago # with `type: timeago` +# `locale: es` +27 de marzo de 2021 # with `type: date` +27 de marzo de 2021 13:57:28 # with `type: datetime` +hace 2 semanas # with `type: timeago` ``` === ":octicons-file-code-16: mkdocs.yml" @@ -70,9 +73,13 @@ hace 2 semanas # `locale: es` with `type: timeago` ```yaml plugins: - git-revision-date-localized: - locale: en + locale: en_US ``` +!!! note when using `type: timeago` + + When using `type: timeago` then [timeago.js](https://github.com/hustcc/timeago.js) is added to your website, which supports [these locales](https://github.com/hustcc/timeago.js/tree/master/src/lang). If you specify a locale not supported by timeago.js, the fallback is English (`en`). It might happen that your specific locale is supported by babel (used by date formats) but not by timeago. In that case open an issue with this plugin. + ## `fallback_to_build_date` @@ -155,3 +162,30 @@ Default is `true`. When enabled, the logs will show warnings when something is w - git-revision-date-localized: strict: true ``` + +## `ignored_commits_file` + +Default is `None`. You can specify a file path (relative to your `mkdocs.yml` directory) that contains a list of commit hashes to ignore +when determining the revision date. The format of the file is the same as the format of +git `blame.ignoreRevsFile`. This can be useful to ignore specific commits that apply formatting updates or other mass changes to the documents. + + +=== ":octicons-file-code-16: mkdocs.yml" + + ```yaml + plugins: + - git-revision-date-localized: + ignored_commits_file: .git-blame-ignore-revs + ``` + +## `enable_parallel_processing` + +Default is `true`. When enabled, the plugin will use `multiprocessing` to iterate through all site files in parallel. Disable if you encounter any errors (and open an issue!). + +=== ":octicons-file-code-16: mkdocs.yml" + + ```yaml + plugins: + - git-revision-date-localized: + enable_parallel_processing: True + ``` diff --git a/mkdocs.yml b/mkdocs.yml index ab61ca8..5859daa 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -60,8 +60,8 @@ markdown_extensions: - pymdownx.tabbed: alternate_style: true - pymdownx.emoji: - emoji_index: !!python/name:materialx.emoji.twemoji - emoji_generator: !!python/name:materialx.emoji.to_svg + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg options: custom_icons: - site/overrides/.icons \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 46e2a74..1fb6605 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,13 @@ classifiers=[ "License :: OSI Approved :: MIT License", ] -dynamic = ["version","dependencies","optional-dependencies"] +dynamic = ["version"] +dependencies = [ + "babel>=2.7.0", + "gitpython>=3.1.44", + "mkdocs>=1.0", + "pytz>=2025.1", +] [project.urls] "Homepage" = "https://github.com/timvink/mkdocs-git-revision-date-localized-plugin" @@ -39,12 +45,6 @@ dynamic = ["version","dependencies","optional-dependencies"] [tool.setuptools.dynamic] version = {attr = "mkdocs_git_revision_date_localized_plugin.__version__"} -dependencies={file = ["requirements.txt"]} - -optional-dependencies.dev={file = ["requirements_dev.txt"]} -optional-dependencies.base={file = ["requirements.txt"]} -optional-dependencies.all={file = ["requirements.txt", "requirements_dev.txt"]} - [tool.pytest.ini_options] markers = [ "serial", @@ -114,5 +114,15 @@ fix = true [tool.uv] dev-dependencies = [ + "click>=8.1.8", + "codecov>=2.1.13", + "mkdocs-gen-files>=0.5.0", + "mkdocs-git-authors-plugin>=0.9.2", + "mkdocs-material>=9.6.7", + "mkdocs-techdocs-core", + "mkdocs-monorepo-plugin>=1.1.0", + "mkdocs-static-i18n>=1.3.0", + "pytest>=8.3.5", + "pytest-cov>=5.0.0", "ruff", -] \ No newline at end of file +] diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 45ba908..0000000 --- a/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -mkdocs>=1.0 -GitPython -babel>=2.7.0 -pytz \ No newline at end of file diff --git a/requirements_dev.txt b/requirements_dev.txt deleted file mode 100644 index 66f09e3..0000000 --- a/requirements_dev.txt +++ /dev/null @@ -1,8 +0,0 @@ -pytest -pytest-cov -codecov -click -mkdocs-material -mkdocs-static-i18n -mkdocs-gen-files -mkdocs-git-authors-plugin \ No newline at end of file diff --git a/src/mkdocs_git_revision_date_localized_plugin/__init__.py b/src/mkdocs_git_revision_date_localized_plugin/__init__.py index 9e2406e..41affe5 100644 --- a/src/mkdocs_git_revision_date_localized_plugin/__init__.py +++ b/src/mkdocs_git_revision_date_localized_plugin/__init__.py @@ -1 +1 @@ -__version__ = "1.3.0" \ No newline at end of file +__version__ = "1.4.5" \ No newline at end of file diff --git a/src/mkdocs_git_revision_date_localized_plugin/ci.py b/src/mkdocs_git_revision_date_localized_plugin/ci.py index 73df3a0..22b3bb4 100644 --- a/src/mkdocs_git_revision_date_localized_plugin/ci.py +++ b/src/mkdocs_git_revision_date_localized_plugin/ci.py @@ -20,7 +20,6 @@ def raise_ci_warnings(repo) -> None: n_commits = commit_count(repo) - # Gitlab Runners if os.getenv("GITLAB_CI") is not None and n_commits < 50: # Default is GIT_DEPTH of 50 for gitlab @@ -43,8 +42,8 @@ def raise_ci_warnings(repo) -> None: [git-revision-date-localized-plugin] Running on GitHub Actions might lead to wrong Git revision dates due to a shallow git fetch depth. - Try setting fetch-depth to 0 in your GitHub Action - (see https://github.com/actions/checkout). + Try setting `fetch-depth: 0` in your GitHub Action. + See https://github.com/actions/checkout for more information. """ ) @@ -76,7 +75,6 @@ def raise_ci_warnings(repo) -> None: ) - def commit_count(repo) -> int: """ Determine the number of commits in a repository. @@ -87,7 +85,7 @@ def commit_count(repo) -> int: Returns: count (int): Number of commits. """ - return int(repo.rev_list('--count','HEAD')) + return int(repo.rev_list("--count", "HEAD")) def is_shallow_clone(repo) -> bool: diff --git a/src/mkdocs_git_revision_date_localized_plugin/dates.py b/src/mkdocs_git_revision_date_localized_plugin/dates.py index 17266fd..c66e4a5 100644 --- a/src/mkdocs_git_revision_date_localized_plugin/dates.py +++ b/src/mkdocs_git_revision_date_localized_plugin/dates.py @@ -1,15 +1,11 @@ - -from babel.dates import format_date, get_timezone +from babel.dates import format_date, get_timezone, format_datetime from datetime import datetime, timezone from typing import Any, Dict def get_date_formats( - unix_timestamp: float, - locale: str = "en", - time_zone: str = "UTC", - custom_format: str = "%d. %B %Y" + unix_timestamp: float, locale: str = "en", time_zone: str = "UTC", custom_format: str = "%d. %B %Y" ) -> Dict[str, Any]: """ Calculate different date formats / types. @@ -25,11 +21,9 @@ def get_date_formats( """ assert time_zone is not None assert locale is not None - + utc_revision_date = datetime.fromtimestamp(int(unix_timestamp), tz=timezone.utc) - loc_revision_date = utc_revision_date.replace( - tzinfo=get_timezone("UTC") - ).astimezone(get_timezone(time_zone)) + loc_revision_date = utc_revision_date.replace(tzinfo=get_timezone("UTC")).astimezone(get_timezone(time_zone)) return { "date": format_date(loc_revision_date, format="long", locale=locale), @@ -42,6 +36,56 @@ def get_date_formats( "iso_date": loc_revision_date.strftime("%Y-%m-%d"), "iso_datetime": loc_revision_date.strftime("%Y-%m-%d %H:%M:%S"), "timeago": '' % (loc_revision_date.isoformat(), locale), - "custom": loc_revision_date.strftime(custom_format), + "custom": format_datetime(loc_revision_date, format=strftime_to_babel_format(custom_format), locale=locale), } - \ No newline at end of file + + +def strftime_to_babel_format(fmt: str) -> str: + """ + Convert strftime format string to Babel format pattern. + + Args: + fmt (str): strftime format string + + Returns: + str: Babel format pattern + """ + # Dictionary mapping strftime directives to Babel format patterns + mapping = { + "%a": "EEE", # Weekday abbreviated + "%A": "EEEE", # Weekday full + "%b": "MMM", # Month abbreviated + "%B": "MMMM", # Month full + "%c": "", # Locale's date and time (not directly mappable) + "%d": "dd", # Day of month zero-padded + "%-d": "d", # Day of month + "%e": "d", # Day of month space-padded + "%f": "SSSSSS", # Microsecond + "%H": "HH", # Hour 24h zero-padded + "%-H": "H", # Hour 24h + "%I": "hh", # Hour 12h zero-padded + "%-I": "h", # Hour 12h + "%j": "DDD", # Day of year + "%m": "MM", # Month zero-padded + "%-m": "M", # Month + "%M": "mm", # Minute zero-padded + "%-M": "m", # Minute + "%p": "a", # AM/PM + "%S": "ss", # Second zero-padded + "%-S": "s", # Second + "%w": "e", # Weekday as number + "%W": "w", # Week of year + "%x": "", # Locale's date (not directly mappable) + "%X": "", # Locale's time (not directly mappable) + "%y": "yy", # Year without century + "%Y": "yyyy", # Year with century + "%z": "Z", # UTC offset + "%Z": "z", # Timezone name + "%%": "%", # Literal % + } + + result = fmt + for strftime_code, babel_code in mapping.items(): + result = result.replace(strftime_code, babel_code) + + return result diff --git a/src/mkdocs_git_revision_date_localized_plugin/exclude.py b/src/mkdocs_git_revision_date_localized_plugin/exclude.py index 0a44688..a5d91d0 100644 --- a/src/mkdocs_git_revision_date_localized_plugin/exclude.py +++ b/src/mkdocs_git_revision_date_localized_plugin/exclude.py @@ -3,6 +3,7 @@ Inspired by https://github.com/apenwarr/mkdocs-exclude """ + import os import fnmatch from typing import List diff --git a/src/mkdocs_git_revision_date_localized_plugin/plugin.py b/src/mkdocs_git_revision_date_localized_plugin/plugin.py index 4b7fef2..d9d74bc 100644 --- a/src/mkdocs_git_revision_date_localized_plugin/plugin.py +++ b/src/mkdocs_git_revision_date_localized_plugin/plugin.py @@ -4,10 +4,13 @@ https://www.mkdocs.org/ https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/ """ + import logging import re import os import time +import multiprocessing +from pathlib import Path from mkdocs import __version__ as mkdocs_version from mkdocs.config import config_options @@ -15,16 +18,19 @@ from mkdocs.structure.nav import Page from mkdocs.utils import copy_file from mkdocs.exceptions import ConfigurationError +from mkdocs.config.defaults import MkDocsConfig +from mkdocs.structure.files import Files from mkdocs_git_revision_date_localized_plugin.util import Util from mkdocs_git_revision_date_localized_plugin.exclude import exclude -from typing import Any, Dict +from typing import Any, Dict, Optional from collections import OrderedDict from packaging.version import Version -HERE = os.path.dirname(os.path.abspath(__file__)) +HERE = Path(__file__).parent.absolute() + class GitRevisionDateLocalizedPlugin(BasePlugin): """ @@ -43,9 +49,16 @@ class GitRevisionDateLocalizedPlugin(BasePlugin): ("enable_creation_date", config_options.Type(bool, default=False)), ("enabled", config_options.Type(bool, default=True)), ("strict", config_options.Type(bool, default=True)), - ("enable_git_follow", config_options.Type(bool, default=True)) + ("enable_git_follow", config_options.Type(bool, default=True)), + ("ignored_commits_file", config_options.Type(str, default=None)), + ("enable_parallel_processing", config_options.Type(bool, default=True)), ) + def __init__(self): + super().__init__() + self.last_revision_commits = {} + self.created_commits = {} + def on_config(self, config: config_options.Config, **kwargs) -> Dict[str, Any]: """ Determine which locale to use. @@ -61,42 +74,41 @@ def on_config(self, config: config_options.Config, **kwargs) -> Dict[str, Any]: Returns: dict: global configuration object """ - if not self.config.get('enabled'): + if not self.config.get("enabled"): return config - - assert self.config['type'] in ["date","datetime","iso_date","iso_datetime","timeago","custom"] - self.util = Util(config=self.config) + assert self.config["type"] in ["date", "datetime", "iso_date", "iso_datetime", "timeago", "custom"] + + self.util = Util( + config=self.config, mkdocs_dir=os.path.abspath(os.path.dirname(config.get("config_file_path"))) + ) # Save last commit timestamp for entire site - self.last_site_revision_timestamp = self.util.get_git_commit_timestamp( - config.get('docs_dir') + self.last_site_revision_hash, self.last_site_revision_timestamp = self.util.get_git_commit_timestamp( + config.get("docs_dir") ) # Get locale from plugin configuration plugin_locale = self.config.get("locale", None) - # theme locale + # Get locale from theme configuration if "theme" in config and "language" in config.get("theme"): custom_theme = config.get("theme") - theme_locale = custom_theme["language"] if Version(mkdocs_version) >= Version("1.6.0") else custom_theme._vars.get("language") - logging.debug( - "Locale '%s' extracted from the custom theme: '%s'" - % (theme_locale, custom_theme.name) + theme_locale = ( + custom_theme["language"] + if Version(mkdocs_version) >= Version("1.6.0") + else custom_theme._vars.get("language") ) + logging.debug("Locale '%s' extracted from the custom theme: '%s'" % (theme_locale, custom_theme.name)) elif "theme" in config and "locale" in config.get("theme"): custom_theme = config.get("theme") - theme_locale = custom_theme.locale if Version(mkdocs_version) >= Version("1.6.0") else custom_theme._vars.get("locale") - logging.debug( - "Locale '%s' extracted from the custom theme: '%s'" - % (theme_locale, custom_theme.name) + theme_locale = ( + custom_theme.locale if Version(mkdocs_version) >= Version("1.6.0") else custom_theme._vars.get("locale") ) - + logging.debug("Locale '%s' extracted from the custom theme: '%s'" % (theme_locale, custom_theme.name)) else: theme_locale = None - logging.debug( - "No locale found in theme configuration (or no custom theme set)" - ) + logging.debug("No locale found in theme configuration (or no custom theme set)") # First prio: plugin locale if plugin_locale: @@ -105,10 +117,7 @@ def on_config(self, config: config_options.Config, **kwargs) -> Dict[str, Any]: # Second prio: theme locale elif theme_locale: locale_set = theme_locale - logging.debug( - "Locale not set in plugin. Fallback to theme configuration: %s" - % locale_set - ) + logging.debug("Locale not set in plugin. Fallback to theme configuration: %s" % locale_set) # Lastly, fallback is English else: locale_set = "en" @@ -116,19 +125,14 @@ def on_config(self, config: config_options.Config, **kwargs) -> Dict[str, Any]: # Validate locale locale_set = str(locale_set) - assert len(locale_set) == 2, "locale must be a 2 letter code, see https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes" # set locale also in plugin configuration self.config["locale"] = locale_set # Add pointers to support files for timeago.js if self.config.get("type") == "timeago": - config["extra_javascript"] = ["js/timeago_mkdocs_material.js"] + config[ - "extra_javascript" - ] - config["extra_javascript"] = ["js/timeago.min.js"] + config[ - "extra_javascript" - ] + config["extra_javascript"] = ["js/timeago_mkdocs_material.js"] + config["extra_javascript"] + config["extra_javascript"] = ["js/timeago.min.js"] + config["extra_javascript"] config["extra_css"] = ["css/timeago.css"] + config["extra_css"] # Compatibility with mkdocs-static-i18n @@ -138,12 +142,65 @@ def on_config(self, config: config_options.Config, **kwargs) -> Dict[str, Any]: msg = "[git-revision-date-localized] should be defined after the i18n plugin in your mkdocs.yml file. " msg += "This is because i18n adds a 'locale' variable to markdown pages that this plugin supports." raise ConfigurationError(msg) - + return config - def on_page_markdown( - self, markdown: str, page: Page, config: config_options.Config, files, **kwargs - ) -> str: + def parallel_compute_commit_timestamps(self, files, original_source: Optional[Dict] = None, is_first_commit=False): + pool = multiprocessing.Pool(processes=min(10, multiprocessing.cpu_count())) + results = [] + for f in files: + if not f.is_documentation_page(): + continue + elif getattr(f, "generated_by", None): + continue + elif f.abs_src_path is None: + continue + elif exclude(f.src_path, self.config.get("exclude", [])): + continue + else: + abs_src_path = f.abs_src_path + # Support plugins like monorepo that might have moved the files from the original source that is under git + if original_source and abs_src_path in original_source: + abs_src_path = original_source[abs_src_path] + + assert Path(abs_src_path).exists() + abs_src_path = str(Path(abs_src_path).absolute()) + result = pool.apply_async(self.util.get_git_commit_timestamp, args=(abs_src_path, is_first_commit)) + results.append((abs_src_path, result)) + pool.close() + pool.join() + if is_first_commit: + for src_uri, result in results: + self.created_commits[src_uri] = result.get() + else: + for src_uri, result in results: + self.last_revision_commits[src_uri] = result.get() + + def on_files(self, files: Files, config: MkDocsConfig): + """ + Compute commit timestamps for all files in parallel. + """ + if not self.config.get("enabled") or not self.config.get("enable_parallel_processing"): + return + + # Support monorepo/techdocs, which copies the docs_dir to a temporary directory + mono_repo_plugin = config.get("plugins", {}).get("monorepo", None) + if mono_repo_plugin is not None and hasattr(mono_repo_plugin, "merger") and mono_repo_plugin.merger is not None: + original_source = mono_repo_plugin.merger.files_source_dir + else: + original_source = None + + try: + if not self.last_revision_commits: + self.parallel_compute_commit_timestamps(files=files, original_source=original_source, is_first_commit=False) + if not self.created_commits: + self.parallel_compute_commit_timestamps(files=files, original_source=original_source, is_first_commit=True) + except Exception as e: + logging.warning(f"Parallel processing failed: {str(e)}.\n To fall back to serial processing, use 'enable_parallel_processing: False' setting.") + raise e + + + def on_page_markdown(self, markdown: str, page: Page, config: config_options.Config, files, **kwargs) -> str: """ Replace jinja2 tags in markdown and templates with the localized dates. @@ -163,7 +220,7 @@ def on_page_markdown( Returns: str: Markdown source text of page as string """ - if not self.config.get('enabled'): + if not self.config.get("enabled"): return markdown # Exclude pages specified in config @@ -177,38 +234,39 @@ def on_page_markdown( # First prio is use mkdocs-static-i18n locale if set try: locale = page.file.locale - except AttributeError: locale = None # Second prio is a frontmatter variable 'locale' set in the markdown if not locale: if "locale" in page.meta: - locale = page.meta['locale'] + locale = page.meta["locale"] # Finally, if no page locale set, we take the locale determined on_config() + # (fourth prio is plugin configuration) + # (firth prio is theme configuration) + # (sixth prio is fallback to English) if not locale: locale = self.config.get("locale") - - # MkDocs supports 2-letter and 5-letter locales - # https://www.mkdocs.org/user-guide/localizing-your-theme/#supported-locales - # We need the 2 letter variant - if len(locale) == 5: - locale = locale[:2] - assert len(locale) == 2, "locale must be a 2 letter code, see https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes" - + # Retrieve git commit timestamp # Except for generated pages (f.e. by mkdocs-gen-files plugin) if getattr(page.file, "generated_by", None): - last_revision_timestamp = int(time.time()) + last_revision_hash, last_revision_timestamp = "", int(time.time()) else: - last_revision_timestamp = self.util.get_git_commit_timestamp( + last_revision_hash, last_revision_timestamp = self.last_revision_commits.get( + str(Path(page.file.abs_src_path).absolute()), (None, None) + ) + if last_revision_timestamp is None: + last_revision_hash, last_revision_timestamp = self.util.get_git_commit_timestamp( path=page.file.abs_src_path, is_first_commit=False, - ) + ) # Last revision date - revision_dates = self.util.get_date_formats_for_timestamp(last_revision_timestamp, locale=locale, add_spans=True) + revision_dates = self.util.get_date_formats_for_timestamp( + last_revision_timestamp, locale=locale, add_spans=True + ) revision_date = revision_dates[self.config["type"]] # timeago output is dynamic, which breaks when you print a page @@ -220,7 +278,11 @@ def on_page_markdown( # Add to page meta information, for developers # Include variants without the CSS elements (raw date strings) page.meta["git_revision_date_localized"] = revision_date - revision_dates_raw = self.util.get_date_formats_for_timestamp(last_revision_timestamp, locale=locale, add_spans=False) + page.meta["git_revision_date_localized_hash"] = last_revision_hash + page.meta["git_revision_date_localized_tag"] = self.util.get_tag_name_for_commit(last_revision_hash) + revision_dates_raw = self.util.get_date_formats_for_timestamp( + last_revision_timestamp, locale=locale, add_spans=False + ) for date_type, date_string in revision_dates_raw.items(): page.meta["git_revision_date_localized_raw_%s" % date_type] = date_string @@ -233,12 +295,20 @@ def on_page_markdown( ) # Also add site last updated information, for developers - site_dates = self.util.get_date_formats_for_timestamp(self.last_site_revision_timestamp, locale=locale, add_spans=True) + page.meta["git_site_revision_date_localized_hash"] = self.last_site_revision_hash + page.meta["git_site_revision_date_localized_tag"] = self.util.get_tag_name_for_commit( + self.last_site_revision_hash + ) + site_dates = self.util.get_date_formats_for_timestamp( + self.last_site_revision_timestamp, locale=locale, add_spans=True + ) site_date = site_dates[self.config["type"]] if self.config["type"] == "timeago": site_date += site_dates["iso_date"] page.meta["git_site_revision_date_localized"] = site_date - site_dates_raw = self.util.get_date_formats_for_timestamp(self.last_site_revision_timestamp, locale=locale, add_spans=False) + site_dates_raw = self.util.get_date_formats_for_timestamp( + self.last_site_revision_timestamp, locale=locale, add_spans=False + ) for date_type, date_string in site_dates_raw.items(): page.meta["git_site_revision_date_localized_raw_%s" % date_type] = date_string @@ -250,24 +320,36 @@ def on_page_markdown( flags=re.IGNORECASE, ) - # If creation date not enabled, return markdown # This is for speed: prevents another `git log` operation each file if not self.config.get("enable_creation_date"): return markdown - + # Retrieve git commit timestamp # Except for generated pages (f.e. by mkdocs-gen-files plugin) if getattr(page.file, "generated_by", None): - first_revision_timestamp = int(time.time()) + first_revision_hash, first_revision_timestamp = "", int(time.time()) else: - first_revision_timestamp = self.util.get_git_commit_timestamp( - path=page.file.abs_src_path, - is_first_commit=True, + first_revision_hash, first_revision_timestamp = self.created_commits.get( + str(Path(page.file.abs_src_path).absolute()), (None, None) ) + if first_revision_timestamp is None: + first_revision_hash, first_revision_timestamp = self.util.get_git_commit_timestamp( + path=page.file.abs_src_path, + is_first_commit=True, + ) + + if first_revision_timestamp > last_revision_timestamp: + # See also https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/issues/111 + msg = "First revision timestamp is older than last revision timestamp for page %s. " % page.file.src_path + msg += "This can be due to a quick in `git` follow behaviour. You can try to set `enable_git_follow: false` in the plugin configuration." + logging.warning(msg) + first_revision_hash, first_revision_timestamp = last_revision_hash, last_revision_timestamp # Creation date formats - creation_dates = self.util.get_date_formats_for_timestamp(first_revision_timestamp, locale=locale, add_spans=True) + creation_dates = self.util.get_date_formats_for_timestamp( + first_revision_timestamp, locale=locale, add_spans=True + ) creation_date = creation_dates[self.config["type"]] # timeago output is dynamic, which breaks when you print a page @@ -278,8 +360,12 @@ def on_page_markdown( # Add to page meta information, for developers # Include variants without the CSS elements (raw date strings) + page.meta["git_creation_date_localized_hash"] = first_revision_hash + page.meta["git_creation_date_localized_tag"] = self.util.get_tag_name_for_commit(first_revision_hash) page.meta["git_creation_date_localized"] = creation_date - creation_dates_raw = self.util.get_date_formats_for_timestamp(first_revision_timestamp, locale=locale, add_spans=False) + creation_dates_raw = self.util.get_date_formats_for_timestamp( + first_revision_timestamp, locale=locale, add_spans=False + ) for date_type, date_string in creation_dates_raw.items(): page.meta["git_creation_date_localized_raw_%s" % date_type] = date_string @@ -300,14 +386,14 @@ def on_post_build(self, config: Dict[str, Any], **kwargs) -> None: Adds the timeago assets to the build. """ # Add timeago files: - if self.config.get("type") == "timeago" and self.config.get('enabled'): + if self.config.get("type") == "timeago" and self.config.get("enabled"): files = [ "js/timeago.min.js", "js/timeago_mkdocs_material.js", "css/timeago.css", ] - for file in files: - dest_file_path = os.path.join(config["site_dir"], file) - src_file_path = os.path.join(HERE, file) - assert os.path.exists(src_file_path) - copy_file(src_file_path, dest_file_path) + for f in files: + dest_file_path = Path(config["site_dir"]) / f + src_file_path = HERE / f + assert src_file_path.exists() + copy_file(str(src_file_path), str(dest_file_path)) diff --git a/src/mkdocs_git_revision_date_localized_plugin/util.py b/src/mkdocs_git_revision_date_localized_plugin/util.py index 275f6b5..5c43cca 100644 --- a/src/mkdocs_git_revision_date_localized_plugin/util.py +++ b/src/mkdocs_git_revision_date_localized_plugin/util.py @@ -1,7 +1,9 @@ """Utility class for mkdocs plugin.""" + import logging import os import time +from pathlib import Path from mkdocs_git_revision_date_localized_plugin.ci import raise_ci_warnings from mkdocs_git_revision_date_localized_plugin.dates import get_date_formats @@ -16,7 +18,7 @@ NoSuchPathError, ) -from typing import Dict +from typing import Dict, List, Tuple logger = logging.getLogger("mkdocs.plugins") @@ -27,11 +29,15 @@ class Util: This helps find git and calculate relevant dates. """ - def __init__(self, config={}): + def __init__(self, config: Dict, mkdocs_dir: str): """Initialize utility class.""" self.config = config self.repo_cache = {} + ignore_commits_file = self.config.get("ignored_commits_file") + ignore_commits_filepath = Path(mkdocs_dir) / ignore_commits_file if ignore_commits_file else None + self.ignored_commits = self.parse_git_ignore_revs(ignore_commits_filepath) if ignore_commits_file else [] + def _get_repo(self, path: str) -> Git: if not os.path.isdir(path): path = os.path.dirname(path) @@ -44,12 +50,7 @@ def _get_repo(self, path: str) -> Git: return self.repo_cache[path] - - def get_git_commit_timestamp( - self, - path: str, - is_first_commit: bool = False - ) -> int: + def get_git_commit_timestamp(self, path: str, is_first_commit: bool = False) -> Tuple[str, int]: """ Get a list of commit dates in unix timestamp, starts with the most recent commit. @@ -60,14 +61,16 @@ def get_git_commit_timestamp( is_first_commit (bool): retrieve commit timestamp when file was created. Returns: - int: commit date in unix timestamp, starts with the most recent commit. + tuple[str, int]: commit hash and commit date in unix timestamp. """ commit_timestamp = "" + commit_hash = "" + n_ignored_commits = 0 # Determine the logging level # Only log warnings when plugin is set to strict. # That way, users turn those into errors using mkdocs build --strict - if self.config.get('strict'): + if self.config.get("strict"): log = logger.warning else: log = logger.info @@ -80,14 +83,15 @@ def get_git_commit_timestamp( realpath = os.path.realpath(path) git = self._get_repo(realpath) - follow_option=self.config.get('enable_git_follow') + follow_option = self.config.get("enable_git_follow") + # Ignored commits are only considered for the most recent update, not for creation if is_first_commit: # diff_filter="A" will select the commit that created the file commit_timestamp = git.log( realpath, date="unix", format="%at", diff_filter="Ar", no_show_signature=True, follow=follow_option ) - # A file can be created multiple times, through a file renamed. + # A file can be created multiple times, through a file renamed. # Commits are ordered with most recent commit first # Get the oldest commit only if commit_timestamp != "": @@ -95,13 +99,41 @@ def get_git_commit_timestamp( else: # Latest commit touching a specific file commit_timestamp = git.log( - realpath, date="unix", format="%at", - diff_filter="r", n=1, no_show_signature=True, follow=follow_option, - ignore_all_space=True, ignore_blank_lines=True + realpath, + date="unix", + format="%at", + diff_filter="r", + n=1, + no_show_signature=True, + follow=follow_option, + ignore_all_space=True, + ignore_blank_lines=True, ) + # Retrieve the history for the file in the format + # The maximum number of commits we will ever need to examine is 1 more than the number of ignored commits. + lines = git.log( + realpath, + date="unix", + format="%H %at", + n=len(self.ignored_commits) + 1, + no_show_signature=True, + ).split("\n") + + # process the commits for the file in reverse-chronological order. Ignore any commit that is on the + # ignored list. If the line is empty, we've reached the end and need to use the fallback behavior. + for line in lines: + if not line: + commit_timestamp = "" + break + commit_hash, commit_timestamp = line.split(" ") + if not any(commit_hash.startswith(x) for x in self.ignored_commits): + break + else: + n_ignored_commits += 1 + except (InvalidGitRepositoryError, NoSuchPathError) as err: - if self.config.get('fallback_to_build_date'): + if self.config.get("fallback_to_build_date"): log( "[git-revision-date-localized-plugin] Unable to find a git directory and/or git is not installed." " Option 'fallback_to_build_date' set to 'true': Falling back to build date" @@ -114,22 +146,22 @@ def get_git_commit_timestamp( ) raise err except GitCommandError as err: - if self.config.get('fallback_to_build_date'): + if self.config.get("fallback_to_build_date"): log( "[git-revision-date-localized-plugin] Unable to read git logs of '%s'. Is git log readable?" - " Option 'fallback_to_build_date' set to 'true': Falling back to build date" - % path + " Option 'fallback_to_build_date' set to 'true': Falling back to build date" % path ) commit_timestamp = time.time() else: logger.error( "[git-revision-date-localized-plugin] Unable to read git logs of '%s'. " - " To ignore this error, set option 'fallback_to_build_date: true'" - % path + " To ignore this error, set option 'fallback_to_build_date: true'" % path ) raise err except GitCommandNotFound as err: - if self.config.get('fallback_to_build_date'): + if "detected dubious ownership" in str(err): + raise err + if self.config.get("fallback_to_build_date"): log( "[git-revision-date-localized-plugin] Unable to perform command: 'git log'. Is git installed?" " Option 'fallback_to_build_date' set to 'true': Falling back to build date" @@ -141,16 +173,29 @@ def get_git_commit_timestamp( " To ignore this error, set option 'fallback_to_build_date: true'" ) raise err + except Exception as err: + if self.config.get("fallback_to_build_date"): + log( + "[git-revision-date-localized-plugin] An unexpected error occurred: %s" + " Option 'fallback_to_build_date' set to 'true': Falling back to build date" % str(err) + ) + commit_timestamp = time.time() + else: + logger.error( + "[git-revision-date-localized-plugin] An unexpected error occurred: %s" + " To ignore this error, set option 'fallback_to_build_date: true'" % str(err) + ) + raise err # create timestamp if commit_timestamp == "": commit_timestamp = time.time() - log( - "[git-revision-date-localized-plugin] '%s' has no git logs, using current timestamp" - % path - ) + msg = "[git-revision-date-localized-plugin] '%s' has no git logs, using current timestamp" % path + if n_ignored_commits: + msg += f" (ignored {n_ignored_commits} commits)" + log(msg) - return int(commit_timestamp) + return commit_hash, int(commit_timestamp) def get_date_formats_for_timestamp( self, @@ -170,25 +215,78 @@ def get_date_formats_for_timestamp( dict: Localized date variants. """ date_formats = get_date_formats( - unix_timestamp=commit_timestamp, + unix_timestamp=commit_timestamp, time_zone=self.config.get("timezone"), locale=locale, - custom_format=self.config.get('custom_format') + custom_format=self.config.get("custom_format"), ) if add_spans: date_formats = self.add_spans(date_formats) return date_formats - @staticmethod def add_spans(date_formats: Dict[str, str]) -> Dict[str, str]: """ Wraps the date string in elements with CSS identifiers. """ + datetime_string = date_formats["datetime"] for date_type, date_string in date_formats.items(): date_formats[date_type] = ( - '%s' - % (date_type, date_string) + '%s' + % (date_type, datetime_string, date_string) ) return date_formats + + @staticmethod + def parse_git_ignore_revs(filename: str) -> List[str]: + """ + Parses a file that is the same format as git's blame.ignoreRevsFile and return the list of commit hashes. + + Whitespace, blanklines and comments starting with # are all ignored. + """ + result = [] + + try: + with open(filename, "rt", encoding="utf-8") as f: + for line in f: + line = line.split("#", 1)[0].strip() + if not line: + continue + result.append(line) + except FileNotFoundError: + logger.error(f"File not found: {filename}") + except Exception as e: + logger.error(f"An error occurred while reading the file {filename}: {e}") + + return result + + def get_tag_name_for_commit(self, commit_hash: str) -> str: + """ + Get the tag name for a specific commit. + + Args: + commit_hash (str): The commit hash to find tags for + + Returns: + str: Tag name if found, otherwise empty string + """ + if not commit_hash: + return "" + + try: + for path, git in self.repo_cache.items(): + try: + # Check if there's a tag pointing to this commit + tags = git.tag("--points-at", commit_hash, format="%(refname:short)") + if tags: + # Return first tag if multiple tags exist for the commit + return tags.split("\n")[0] + except GitCommandError: + # Continue checking other repositories in cache + continue + + return "" # No tag found for this commit + except Exception as e: + logger.debug(f"Error getting tag for commit {commit_hash}: {str(e)}") + return "" diff --git a/tests/fixtures/basic_project/.gitignore b/tests/fixtures/basic_project/.gitignore new file mode 100644 index 0000000..ccbfadb --- /dev/null +++ b/tests/fixtures/basic_project/.gitignore @@ -0,0 +1 @@ +site/ \ No newline at end of file diff --git a/tests/fixtures/basic_project/gen_files.py b/tests/fixtures/basic_project/gen_files.py new file mode 100644 index 0000000..8534291 --- /dev/null +++ b/tests/fixtures/basic_project/gen_files.py @@ -0,0 +1,5 @@ +# for testing with generated files. See mkdocs_plugin_genfiles.yml +import mkdocs_gen_files + +with mkdocs_gen_files.open("foo.md", "w") as f: + print("Bar, world!", file=f) \ No newline at end of file diff --git a/tests/fixtures/basic_project/mkdocs_ignored_commits.yml b/tests/fixtures/basic_project/mkdocs_ignored_commits.yml new file mode 100644 index 0000000..6378e33 --- /dev/null +++ b/tests/fixtures/basic_project/mkdocs_ignored_commits.yml @@ -0,0 +1,8 @@ +site_name: test gitrevisiondatelocalized_plugin +use_directory_urls: true + +plugins: + - search + - git-revision-date-localized: + enable_creation_date: True + ignored_commits_file: ignored-commits.txt diff --git a/tests/fixtures/basic_project/mkdocs_no_parallel.yml b/tests/fixtures/basic_project/mkdocs_no_parallel.yml new file mode 100644 index 0000000..8807c99 --- /dev/null +++ b/tests/fixtures/basic_project/mkdocs_no_parallel.yml @@ -0,0 +1,7 @@ +site_name: test gitrevisiondatelocalized_plugin +use_directory_urls: true + +plugins: + - search + - git-revision-date-localized: + enable_parallel_processing: False \ No newline at end of file diff --git a/tests/fixtures/basic_project/mkdocs_plugin_genfiles.yml b/tests/fixtures/basic_project/mkdocs_plugin_genfiles.yml new file mode 100644 index 0000000..abbf9f8 --- /dev/null +++ b/tests/fixtures/basic_project/mkdocs_plugin_genfiles.yml @@ -0,0 +1,9 @@ +site_name: test gitrevisiondatelocalized_plugin +use_directory_urls: true + +plugins: + - search + - gen-files: + scripts: + - gen_files.py # or any other name or path + - git-revision-date-localized \ No newline at end of file diff --git a/tests/fixtures/mkdocs-gen-files/gen_pages.py b/tests/fixtures/mkdocs-gen-files/gen_pages.py index 059b0d4..0825cfb 100644 --- a/tests/fixtures/mkdocs-gen-files/gen_pages.py +++ b/tests/fixtures/mkdocs-gen-files/gen_pages.py @@ -2,4 +2,3 @@ with mkdocs_gen_files.open("foo.md", "w") as f: print("Hello, world!", file=f) - diff --git a/tests/fixtures/monorepo/.gitignore b/tests/fixtures/monorepo/.gitignore new file mode 100644 index 0000000..0c98940 --- /dev/null +++ b/tests/fixtures/monorepo/.gitignore @@ -0,0 +1,2 @@ +site/ +build/ \ No newline at end of file diff --git a/tests/fixtures/monorepo/components/a/docs/README.md b/tests/fixtures/monorepo/components/a/docs/README.md new file mode 100644 index 0000000..b6e496d --- /dev/null +++ b/tests/fixtures/monorepo/components/a/docs/README.md @@ -0,0 +1 @@ +# Docs for A diff --git a/tests/fixtures/monorepo/components/a/mkdocs.yml b/tests/fixtures/monorepo/components/a/mkdocs.yml new file mode 100644 index 0000000..89b78e5 --- /dev/null +++ b/tests/fixtures/monorepo/components/a/mkdocs.yml @@ -0,0 +1,4 @@ +site_name: Component A + +nav: + - Home: "README.md" diff --git a/tests/fixtures/monorepo/components/b/docs/README.md b/tests/fixtures/monorepo/components/b/docs/README.md new file mode 100644 index 0000000..54480bb --- /dev/null +++ b/tests/fixtures/monorepo/components/b/docs/README.md @@ -0,0 +1 @@ +# Docs for B diff --git a/tests/fixtures/monorepo/components/b/mkdocs.yml b/tests/fixtures/monorepo/components/b/mkdocs.yml new file mode 100644 index 0000000..2439516 --- /dev/null +++ b/tests/fixtures/monorepo/components/b/mkdocs.yml @@ -0,0 +1,4 @@ +site_name: Component B + +nav: + - Home: "README.md" diff --git a/tests/fixtures/monorepo/components/c/docs/README.md b/tests/fixtures/monorepo/components/c/docs/README.md new file mode 100644 index 0000000..0ce3a58 --- /dev/null +++ b/tests/fixtures/monorepo/components/c/docs/README.md @@ -0,0 +1 @@ +# Docs for C diff --git a/tests/fixtures/monorepo/components/c/mkdocs.yml b/tests/fixtures/monorepo/components/c/mkdocs.yml new file mode 100644 index 0000000..ffbc6c1 --- /dev/null +++ b/tests/fixtures/monorepo/components/c/mkdocs.yml @@ -0,0 +1,4 @@ +site_name: Component C + +nav: + - Home: "README.md" diff --git a/tests/fixtures/monorepo/components/d/README.md b/tests/fixtures/monorepo/components/d/README.md new file mode 100644 index 0000000..a045e60 --- /dev/null +++ b/tests/fixtures/monorepo/components/d/README.md @@ -0,0 +1,3 @@ +# Component D + +This will not be included diff --git a/tests/fixtures/monorepo/components/d/e/docs/README.md b/tests/fixtures/monorepo/components/d/e/docs/README.md new file mode 100644 index 0000000..c83a82f --- /dev/null +++ b/tests/fixtures/monorepo/components/d/e/docs/README.md @@ -0,0 +1 @@ +# Docs for E diff --git a/tests/fixtures/monorepo/components/d/e/mkdocs.yml b/tests/fixtures/monorepo/components/d/e/mkdocs.yml new file mode 100644 index 0000000..8ec4728 --- /dev/null +++ b/tests/fixtures/monorepo/components/d/e/mkdocs.yml @@ -0,0 +1,4 @@ +site_name: Component E + +nav: + - Home: "README.md" diff --git a/tests/fixtures/monorepo/components/randomfile b/tests/fixtures/monorepo/components/randomfile new file mode 100644 index 0000000..25e04ba --- /dev/null +++ b/tests/fixtures/monorepo/components/randomfile @@ -0,0 +1 @@ +File present to test that it is successfully ignored by wildcard include. diff --git a/tests/fixtures/monorepo/docs/authentication.md b/tests/fixtures/monorepo/docs/authentication.md new file mode 100644 index 0000000..80fbc08 --- /dev/null +++ b/tests/fixtures/monorepo/docs/authentication.md @@ -0,0 +1,10 @@ +# Authentication + +This explains how to authenticate. + +## Authorization Header + +To authenticate, simply pass in your access token in the form of a `Authorization: Bearer {access_token}` header in your HTTP request to our API. + +- Markdown source: `sample-docs/docs/authentication.md` +- Permalink: diff --git a/tests/fixtures/monorepo/docs/index.md b/tests/fixtures/monorepo/docs/index.md new file mode 100644 index 0000000..ce27a1e --- /dev/null +++ b/tests/fixtures/monorepo/docs/index.md @@ -0,0 +1,12 @@ +# Welcome to our Developer Platform + +This contains the documentation for our Developer Platform. + +## API + +- [v1 API Reference](./versions/v1/reference.md) +- [v2 API Reference](./versions/v2/reference.md) +- [v3 API Reference](./versions/v3/reference.md) + +- Markdown source: `sample-docs/docs/index.md` +- Permalink: diff --git a/tests/fixtures/monorepo/mkdocs.yml b/tests/fixtures/monorepo/mkdocs.yml new file mode 100644 index 0000000..3b9798e --- /dev/null +++ b/tests/fixtures/monorepo/mkdocs.yml @@ -0,0 +1,18 @@ +site_name: Cats API + +nav: + - Intro: 'index.md' + - Authentication: 'authentication.md' + - Components: '*include ./components/*/mkdocs.yml' + - API: + - v1: '!include ./v1/mkdocs.yml' + - v2: '!include ./v2/mkdocs.yml' + - v3: '!include ./v3/mkdocs.yml' + +theme: + name: material + +plugins: + - search + - git-revision-date-localized + - monorepo diff --git a/tests/fixtures/monorepo/mkdocs_reverse_order.yml b/tests/fixtures/monorepo/mkdocs_reverse_order.yml new file mode 100644 index 0000000..c341095 --- /dev/null +++ b/tests/fixtures/monorepo/mkdocs_reverse_order.yml @@ -0,0 +1,19 @@ +site_name: Cats API + +nav: + - Intro: 'index.md' + - Authentication: 'authentication.md' + - Components: '*include ./components/*/mkdocs.yml' + - API: + - v1: '!include ./v1/mkdocs.yml' + - v2: '!include ./v2/mkdocs.yml' + - v3: '!include ./v3/mkdocs.yml' + +theme: + name: material + +plugins: + - search + # Note; here monorepo is defined after git-revision-date-localized + - monorepo + - git-revision-date-localized diff --git a/tests/fixtures/monorepo/v1/docs/changelog.md b/tests/fixtures/monorepo/v1/docs/changelog.md new file mode 100644 index 0000000..84b564d --- /dev/null +++ b/tests/fixtures/monorepo/v1/docs/changelog.md @@ -0,0 +1,6 @@ +# Changelog + +This contains the changelog for the v1 API. + +- Markdown source: `sample-docs/v1/docs/changelog.md` +- Permalink: diff --git a/tests/fixtures/monorepo/v1/docs/reference.md b/tests/fixtures/monorepo/v1/docs/reference.md new file mode 100644 index 0000000..4b1fce3 --- /dev/null +++ b/tests/fixtures/monorepo/v1/docs/reference.md @@ -0,0 +1,18 @@ +# v1 API reference + +This contains the v1 API reference. + +## GET /v1/cats + +Returns a list of cats. + +## GET /v1/search + +Parameters: + +- `q` = A string containing the search query for a cat name. + +Returns a list of cats that match the search query. + +- Markdown source: `sample-docs/v1/docs/reference.md` +- Permalink: diff --git a/tests/fixtures/monorepo/v1/mkdocs.yml b/tests/fixtures/monorepo/v1/mkdocs.yml new file mode 100644 index 0000000..ede30e7 --- /dev/null +++ b/tests/fixtures/monorepo/v1/mkdocs.yml @@ -0,0 +1,5 @@ +site_name: versions/v1 + +nav: + - Reference: "reference.md" + - Changelog: "changelog.md" diff --git a/tests/fixtures/monorepo/v2/docs/changelog.md b/tests/fixtures/monorepo/v2/docs/changelog.md new file mode 100644 index 0000000..8b6bdee --- /dev/null +++ b/tests/fixtures/monorepo/v2/docs/changelog.md @@ -0,0 +1,6 @@ +# Changelog + +This contains the changelog for the v2 API. + +- Markdown source: `sample-docs/v2/docs/changelog.md` +- Permalink: diff --git a/tests/fixtures/monorepo/v2/docs/migrating.md b/tests/fixtures/monorepo/v2/docs/migrating.md new file mode 100644 index 0000000..c9f92ef --- /dev/null +++ b/tests/fixtures/monorepo/v2/docs/migrating.md @@ -0,0 +1,6 @@ +# Migration Guide to v2 + +This contains the migration guide to the v2 API from the v1 API. + +- Markdown source: `sample-docs/v2/docs/migrating.md` +- Permalink: diff --git a/tests/fixtures/monorepo/v2/docs/reference.md b/tests/fixtures/monorepo/v2/docs/reference.md new file mode 100644 index 0000000..b8866fd --- /dev/null +++ b/tests/fixtures/monorepo/v2/docs/reference.md @@ -0,0 +1,26 @@ +# v2 API reference + +This contains the v2 API reference. + +## GET /v2/cats + +Returns a list of all cats. + +## GET /v2/breeds + +Returns a list of all breeds of cats. + +## GET /v2/breeds/:breed_name/cats + +Returns a list of all cats under the `:breed_name` breed. + +## GET /v2/search + +Parameters: + +- `q` = A string containing the search query for a cat name or breed. + +Returns a list of cats that match the search query. + +- Markdown source: `sample-docs/v2/docs/reference.md` +- Permalink: diff --git a/tests/fixtures/monorepo/v2/mkdocs.yml b/tests/fixtures/monorepo/v2/mkdocs.yml new file mode 100644 index 0000000..be8ae95 --- /dev/null +++ b/tests/fixtures/monorepo/v2/mkdocs.yml @@ -0,0 +1,6 @@ +site_name: versions/v2 + +nav: + - Migrating to v2: "migrating.md" + - Reference: "reference.md" + - Changelog: "changelog.md" diff --git a/tests/fixtures/monorepo/v3/docs/changelog.md b/tests/fixtures/monorepo/v3/docs/changelog.md new file mode 100644 index 0000000..657408e --- /dev/null +++ b/tests/fixtures/monorepo/v3/docs/changelog.md @@ -0,0 +1,6 @@ +# Changelog + +This contains the changelog for the v3 API. + +- Markdown source: `sample-docs/v3/docs/changelog.md` +- Permalink: diff --git a/tests/fixtures/monorepo/v3/docs/migrating.md b/tests/fixtures/monorepo/v3/docs/migrating.md new file mode 100644 index 0000000..26a856f --- /dev/null +++ b/tests/fixtures/monorepo/v3/docs/migrating.md @@ -0,0 +1,6 @@ +# Migration Guide to v3 + +This contains the migration guide to the v3 API from the v2 API. + +- Markdown source: `sample-docs/v3/docs/migrating.md` +- Permalink: diff --git a/tests/fixtures/monorepo/v3/docs/reference.md b/tests/fixtures/monorepo/v3/docs/reference.md new file mode 100644 index 0000000..156c1b2 --- /dev/null +++ b/tests/fixtures/monorepo/v3/docs/reference.md @@ -0,0 +1,30 @@ +# v3 API reference + +This contains the v3 API reference. + +## GET /v3/cats + +Returns a list of all cats. + +## GET /v3/breeds + +Returns a list of all breeds of cats. + +## GET /v3/breeds/:breed_name/cats + +Returns a list of all cats under the `:breed_name` breed. + +## GET /v3/search + +Parameters: + +- `q` = A string containing the search query for a cat name or breed. + +Returns a list of cats that match the search query. + +- Markdown source: `sample-docs/v3/docs/reference.md` +- Permalink: + +## GET /v3/cat/:name/lives_left + +Returns how many lives the cat named `:name` still has left. diff --git a/tests/fixtures/monorepo/v3/mkdocs.yml b/tests/fixtures/monorepo/v3/mkdocs.yml new file mode 100644 index 0000000..8082133 --- /dev/null +++ b/tests/fixtures/monorepo/v3/mkdocs.yml @@ -0,0 +1,3 @@ +site_name: versions/v3 + +docs_dir: ./docs diff --git a/tests/fixtures/techdocs-core/docs/authentication.md b/tests/fixtures/techdocs-core/docs/authentication.md new file mode 100644 index 0000000..e69de29 diff --git a/tests/fixtures/techdocs-core/docs/index.md b/tests/fixtures/techdocs-core/docs/index.md new file mode 100644 index 0000000..b33485e --- /dev/null +++ b/tests/fixtures/techdocs-core/docs/index.md @@ -0,0 +1,9 @@ +# Welcome to our Developer Platform + +This contains the documentation for our Developer Platform. + +## API + + +- Markdown source: `sample-docs/docs/index.md` +- Permalink: diff --git a/tests/fixtures/techdocs-core/mkdocs.yml b/tests/fixtures/techdocs-core/mkdocs.yml new file mode 100644 index 0000000..df73b72 --- /dev/null +++ b/tests/fixtures/techdocs-core/mkdocs.yml @@ -0,0 +1,13 @@ +site_name: Cats API + +nav: + - Intro: 'index.md' + - Authentication: 'authentication.md' + +theme: + name: material + +plugins: + - techdocs-core + - git-revision-date-localized: + enable_creation_date: true diff --git a/tests/fixtures/with_mknotebooks/docs/demo.ipynb b/tests/fixtures/with_mknotebooks/docs/demo.ipynb index 05bcb32..66ee88a 100644 --- a/tests/fixtures/with_mknotebooks/docs/demo.ipynb +++ b/tests/fixtures/with_mknotebooks/docs/demo.ipynb @@ -1,30 +1,4 @@ { - "metadata": { - "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.8.3-final" - }, - "orig_nbformat": 2, - "kernelspec": { - "name": "Python 3.8.3 64-bit ('base': conda)", - "display_name": "Python 3.8.3 64-bit ('base': conda)", - "metadata": { - "interpreter": { - "hash": "61a9efb557ee20b19fda2d58cb63f9a3bf86c2530fcd43d63aa6e0adea42a5e4" - } - } - } - }, - "nbformat": 4, - "nbformat_minor": 2, "cells": [ { "cell_type": "code", @@ -35,6 +9,7 @@ "import pandas as pd\n", "import numpy as np\n", "import datetime\n", + "\n", "%matplotlib inline" ] }, @@ -44,8 +19,8 @@ "metadata": {}, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "This notebook last ran at 2020-10-26 15:45:16.815445\n" ] @@ -56,11 +31,11 @@ ] }, { + "cell_type": "markdown", + "metadata": {}, "source": [ "## A df" - ], - "cell_type": "markdown", - "metadata": {} + ] }, { "cell_type": "code", @@ -68,8 +43,8 @@ "metadata": {}, "outputs": [ { - "output_type": "execute_result", "data": { + "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
timeamplitude
00.00.000000
10.10.099833
20.20.198669
30.30.295520
40.40.389418
\n
", "text/plain": [ " time amplitude\n", "0 0.0 0.000000\n", @@ -77,39 +52,65 @@ "2 0.2 0.198669\n", "3 0.3 0.295520\n", "4 0.4 0.389418" - ], - "text/html": "
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
timeamplitude
00.00.000000
10.10.099833
20.20.198669
30.30.295520
40.40.389418
\n
" + ] }, + "execution_count": 4, "metadata": {}, - "execution_count": 4 + "output_type": "execute_result" } ], "source": [ - "df = pd.DataFrame({\"time\":np.arange(0, 10, 0.1)})\n", - "df[\"amplitude\"] = np.sin(df.time)\n", + "df = pd.DataFrame({\"time\": np.arange(0, 10, 0.1)})\n", + "df[\"amplitude\"] = np.sin(df.time)\n", "df.head(5)" ] }, { - "source": [ - "ax = df.plot()" - ], "cell_type": "code", - "metadata": {}, "execution_count": 5, + "metadata": {}, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": "
", + "image/png": "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\n", "image/svg+xml": "\n\n\n\n \n \n \n \n 2020-10-26T15:45:51.963649\n image/svg+xml\n \n \n Matplotlib v3.3.2, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXAAAAD4CAYAAAD1jb0+AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAAuKklEQVR4nO3dd3hUVf7H8fdJTyAkJHRCSCABkgChhLIgUlU6KvaKq8tv3V3bqiu7FgIqi72xdhB1dcW2GorSUREpoacnQAIJAVJISC8z5/fHjS4iKCST3Cnf1/PkITOZmfu93MknZ84951yltUYIIYTjcTO7ACGEEI0jAS6EEA5KAlwIIRyUBLgQQjgoCXAhhHBQHi25sXbt2umwsLCW3KQQQji8nTt3Fmqt2595f4sGeFhYGImJiS25SSGEcHhKqZyz3S9dKEII4aAkwIUQwkFJgAshhIP6zT5wpdQSYCpwQmvdt+G+IGAZEAZkA9dorU82poC6ujpyc3Oprq5uzNPFWfj4+BASEoKnp6fZpQghmtH5nMRcCiwC3jvtvjnAeq31QqXUnIbbDzWmgNzcXPz9/QkLC0Mp1ZiXEKfRWlNUVERubi7h4eFmlyOEaEa/2YWitf4WKD7j7hnAuw3fvwtc3tgCqqurCQ4OlvC2EaUUwcHB8olGCBfQ2D7wjlrr/IbvjwEdz/VApdRspVSiUiqxoKDgXI9pZBnibOT/UwjX0OSTmNpYj/aca9Jqrd/UWsdprePat//FOHQhhHBqh4sqmbc8mXqL1eav3dgAP66U6gzQ8O8J25XUskpKSnj11VcBOHr0KFdddZXJFQkhnEFVrYXn16Qz4YVvWLbjCKn5ZTbfRmMDPAG4teH7W4EvbVNOyzs9wLt06cKnn35qckVCCEemtWbV/nwmPP8NL2/IYmJMJzbcP4Z+IQE239b5DCP8DzAGaKeUygXmAguBj5VStwM5wDU2r6yFzJkzhwMHDjBgwAAiIyNJTU0lKSmJpUuX8sUXX1BRUUFmZiYPPPAAtbW1vP/++3h7e7Nq1SqCgoI4cOAAf/7znykoKMDPz4+33nqLPn36mL1bQggTZB4vI355Mt9nFdGnkz/LZg9nWI/gZtvebwa41vr6c/xovI1rYd7yZFKOnrLpa0Z3acPcaTHn/PnChQtJSkpiz549ZGdnM3Xq1J9+lpSUxO7du6muriYiIoKnnnqK3bt3c9999/Hee+9x7733Mnv2bF5//XUiIyPZtm0bf/rTn9iwYYNN90EIYd9OVdfx0rpM3t2STStvD+bPiOGGoaF4uDfvXMkWXczK0YwdOxZ/f3/8/f0JCAhg2rRpAPTr1499+/ZRXl7Oli1buPrqq396Tk1NjVnlCiFamNWq+XRXLk9/nUZRRS3XDQnlwct6E9TKq0W2b1cB/mstZTN4e3v/9L2bm9tPt93c3Kivr8dqtRIYGMiePXtMqlAIYZa9R0qYm5DMniMlDAoN5J1ZQ5uln/vXuPxaKP7+/pSVNe7scJs2bQgPD+eTTz4BjJMXe/futWV5Qgg7U1Rew0Of7uPyV78n92QVz14dy6d/HNHi4Q121gI3Q3BwMCNHjqRv375ERUVd8PM/+OAD7rzzTp544gnq6uq47rrriI2NbYZKhRBmqrdYeX9rDs+vzaCq1sIdF4Vz9/hI/H3MW3NIGfNwWkZcXJw+84IOqampjQpO8evk/1UI2/nhQBHzlieTdqyMiyLaET89mogO/i22faXUTq113Jn3u3wLXAghzuVoSRVPrkpl5b58ugb68vpNg7kspqPdLFchAS6EEGeorrOwePMhFm3Iwqo1906I5I+je+Lj6W52aT8jAS6EEKdZn3qc+StSyCmqZGJMJx6eEkW3ID+zyzorCXAhhAAOFVYwf3kyG9ML6Nm+Fe/fPpRRkfa9AJ8EuBDCpVXU1PPKhiwWbz6It4c7D0+OYtbIMDybeRalLUiACyFcktaahL1HWbAqleOnapg5KISHJvWmg7+P2aWdN/v/E+OgWrduDfx8ido9e/awatWqC36t+Ph4nn32WZvWJ4QrSzl6imvf2Mo9H+2hg78Pn905gueuiXWo8AZpgTe705eo3bNnD4mJiUyePNnkqoRwTSWVtTy3JoMPtuUQ6OfFP6/sxzVx3XB3s49hgRdKWuDA5ZdfzuDBg4mJieHNN98EjBb0gw8+SExMDBMmTGD79u2MGTOGHj16kJCQAMDSpUuZMWMGY8aMITIyknnz5v3itbOzs+nbty+1tbU89thjLFu2jAEDBrBs2bJftKz79u1LdnY2AE8++SS9evXioosuIj09/afHHDhwgIkTJzJ48GBGjRpFWlpaM/7PCOEcLFbNh9sOM/bZTXywLYebh3dn4/1juH5oqMOGN9hbC/yrOXBsv21fs1M/mLTwVx+yZMkSgoKCqKqqYsiQIcycOZOKigrGjRvHM888wxVXXMEjjzzC2rVrSUlJ4dZbb2X69OkAbN++naSkJPz8/BgyZAhTpkwhLu4XE6bw8vJi/vz5JCYmsmjRIsDoGjmbnTt38tFHH7Fnzx7q6+sZNGgQgwcPBpDla4W4QDtzTjI3IYmkvFMMDQ9i3vQYojq3Mbssm7CvADfJyy+/zH//+18Ajhw5QmZmJl5eXkycOBEwlo/19vbG09OTfv36/dRKBrjkkksIDjYWbL/yyivZvHnzWQP8Qnz33XdcccUV+PkZY09//GMhy9cKcf5OlFWz8Ks0Pt+VR6c2Prx8/UCm9e9sN7MobcG+Avw3WsrNYdOmTaxbt44ffvgBPz8/xowZQ3V1NZ6enj8d6LMtJfujM98MF/Lm8PDwwGr934VOq6urf/XxsnytEL+ttt7Ku1uyeWl9JjX1Fv40pid/HhtBK2/7ijtbcPk+8NLSUtq2bYufnx9paWls3br1gp6/du1aiouLqaqq4osvvmDkyJHnfOyZS9eGhYWxa9cuAHbt2sWhQ4cAuPjii/niiy+oqqqirKyM5cuXA7J8rRC/5duMAia99C1PrkplaHgQa+4bzd8m9nHK8AYJcCZOnEh9fT1RUVHMmTOH4cOHX9Dzhw4dysyZM+nfvz8zZ8781e6TsWPHkpKS8tNJzJkzZ1JcXExMTAyLFi2iV69eAAwaNIhrr72W2NhYJk2axJAhQ356jQ8++IDFixcTGxtLTEwMX37psNeTFsJmjhRXMvu9RG5Zsp16q2bxrXEsmTWE8HatzC6tWclysk2wdOnSn52UtCeO/P8qxPmqqrXw2jcHeOObA7gpxV/GRXDHqHC8Pexr0ammkuVkhRBOQ2vN6uRjPL4ilbySKqbFduEfk/vQOcDX7NJalAR4E8yaNYtZs2aZXYYQLiXrRBnxCSlsziqkTyd/Ppo9nOE9gs0uyxR2EeBaa6ca2mO2luwWE6KllFXX8dK6TJZuycbPy51502O4cVgoHg6w6FRzMT3AfXx8KCoqIjg4WELcBrTWFBUV4ePjWGs6CHEuVqvm8915LPwqjaKKGq6N68aDl/UmuLW32aWZzvQADwkJITc3l4KCArNLcRo+Pj6EhISYXYYQTbY/t5THEpLYfbiEAd0CWTIrjv4hgWaXZTdMD3BPT0/Cw8PNLkMIYUeKymt4dk06H+04QnArb569OpYrB3bFzYHXLWkOpge4EEL8qN5i5YNth3luTTqVtRZuHxnO3RMiaePjaXZpdkkCXAhhF7YeLCI+IZm0Y2VcFNGO+OnRRHTwN7ssu9akAFdK3QfcAWhgP3Cb1vrXF/QQQojT5JdWsWBVGsv3HqVroC+v3zSIy2I6yaCG89DoAFdKdQXuBqK11lVKqY+B64ClNqpNCOHEauotvP3dIRZtyMKqNfeMj+SPo3vi6+VcsyibU1O7UDwAX6VUHeAHHG16SUIIZ7ch7Tjzl6eQXVTJZTEdeWRKNN2C/Mwuy+E0OsC11nlKqWeBw0AVsEZrvebMxymlZgOzAUJDQxu7OSGEE8gurGD+ihQ2pJ2gR/tWvPf7oVzcq73ZZTmspnShtAVmAOFACfCJUuomrfW/T3+c1vpN4E0wFrNqfKlCCEdVWVvPog1ZvP3dITzdFf+Y3IdZI8Lx8nDdWZS20JQulAnAIa11AYBS6nNgBPDvX32WEMJlaK1ZsS+fBatSyS+t5sqBXZkzqQ8d2shMYVtoSoAfBoYrpfwwulDGA4m//hQhhKtIzT9FfEIy2w4VE9OlDYtuGMjg7kFml+VUmtIHvk0p9SmwC6gHdtPQVSKEcF2llXU8vzad97fmEODryZNX9OW6IY599Xd71aRRKFrrucBcG9UihHBgFqvm48QjPLM6nZLKWm4YFsoDl/Ym0M/L7NKclszEFEI02a7DJ5n7ZTL780oZEtaW+OlDiekSYHZZTk8CXAjRaCfKqnnqq3Q+25VLxzbevHTdAKbHdpFZlC1EAlwIccHqLFbe3ZLNS+syqa638MfRPblrXITTXv3dXsn/thDignyfVcjchGSyTpQzpnd7HpsaTY/2rc0uyyVJgAshzkvuyUqeWJHK18nHCA3y4+1b4hgf1UG6S0wkAS6E+FXVdRbe+OYgr27Kwk0pHri0F3eM6oGPpyw6ZTYJcCHEWWmtWZ18nCdWppB7soop/Tvz8OQougT6ml2aaCABLoT4hawT5cxbnsx3mYX07ujPh38Yxoie7cwuS5xBAlwI8ZOy6jpeXp/JO99n4+vlzmNTo7n5d93xdJdFp+yRBLgQAqtV89/deSz8Oo3C8hquGdyNByf2pl1rb7NLE79CAlwIF5eUV8rchGR25pwktlsgb98SR2y3QLPLEudBAlwIF1VcUcszq9P5aMdhglt58fTM/lw1OAQ3WXTKYUiAC+Fi6i1WPtx+mOfWZFBeU89tI8K5Z0IkAb6eZpcmLpAEuBAuZNvBIuYmJJN2rIwRPYOJnx5Dr47+ZpclGkkCXAgXcKy0mgWrUknYe5Sugb68euMgJvXtJLMoHZwEuBBOrKbewuLNh1i0IYt6q+bucRHcOSYCXy+ZRekMJMCFcFIb004wf0UKhworuCS6I49OiSY02M/ssoQNSYAL4WSyCyt4fEUK69NO0KNdK979/VBG92pvdlmiGUiAC+EkKmvreXXjAd789iCe7op/TO7DrBHheHnILEpnJQEuhIPTWrNiXz4LVqWSX1rNFQO78vdJfejQxsfs0kQzkwAXwoGlHTtFfEIyWw8WE925Da9cP5C4sCCzyxItRAJcCAdUWlnHC+syeH9rDv4+HjxxeV+uHxqKu8yidCkS4EI4EKtV83HiEZ5enU5JZS03DAvl/kt607aVl9mlCRNIgAvhIHYfPsnchGT25ZYyJKwtc6cNpW/XALPLEiaSABfCzhWU1fDU12l8ujOXDv7evHjtAGYM6CKzKIUEuBD2qs5i5b0fcnhxbQbV9Rb+b3QP7hoXSWtv+bUVBnknCGGHtmQVMjchmcwT5Yzu1Z7HpkXTs31rs8sSdqZJAa6UCgTeBvoCGvi91voHG9QlhEvKPVnJglWprNp/jNAgP96+JY7xUR2ku0ScVVNb4C8BX2utr1JKeQGy0IIQjVBdZ+GNbw7y2jdZANx/SS/+cHEPfDxl0Slxbo0OcKVUAHAxMAtAa10L1NqmLCFcg9aaNSnHeWJlCkeKq5jSrzP/mBJF10Bfs0sTDqApLfBwoAB4RykVC+wE7tFaV5z+IKXUbGA2QGhoaBM2J4RzyTpRzrzlyXyXWUivjq358I5hjIhoZ3ZZwoEorXXjnqhUHLAVGKm13qaUegk4pbV+9FzPiYuL04mJiY2rVAgnUVZdxysbsliy+RC+Xu7cN6EXN/+uO57usuiUODul1E6tddyZ9zelBZ4L5GqttzXc/hSY04TXE8Kpaa35Yk8eC1alUVBWwzVxIfxtYh/atfY2uzThoBod4FrrY0qpI0qp3lrrdGA8kGK70oRwHkl5pcQnJJOYc5LYkADeuiWOAd0CzS5LOLimjkK5C/igYQTKQeC2ppckhPM4WVHLs2vS+XD7YYL8vHh6Zn+uGhyCmyw6JWygSQGutd4D/KJfRghXZ7FqPtx+mOfWpFNWXc+sEWHcO6EXAb6eZpcmnIjMxBTCxnZkFzP3y2RS8k8xvEcQ86b3pXcnf7PLEk5IAlwIGzl+qpp/rkrliz1H6Rzgw6IbBjKlX2eZRSmajQS4EE1UW29lyfeHeGV9JnVWzV3jIrhzTE/8vOTXSzQveYcJ0QSb0k8wf3kKBwsrmBDVkcemRhMaLCtKiJYhAS5EIxwuqmT+ihTWpR4nvF0rlt42hDG9O5hdlnAxEuBCXICqWguvbsrijW8P4uGmeGhiH35/URjeHrLolGh5EuBCnAetNav2H+PJlSkcLa1mxoAu/H1SFJ0CfMwuTbgwCXAhfkPG8TLmfpnMDweLiOrchhevG8jQ8CCzyxJCAlyIcymtquPFdRm890MOrb09eHxGDDcM6467zKIUdkICXIgzWK2aT3fl8tRXaRRX1nL90FAeuLQ3Qa28zC5NiJ+RABfiNHuOlDA3IZm9R0oY3L0t704fSt+uAWaXJcRZSYALARSW1/D012l8nJhLe39vXrg2lssHdJVZlMKuSYALl1ZnsfL+Dzm8sC6DqloLsy/uwV3jIvD3kUWnhP2TABcua8uBQuITksk4Xs6oyHbMnRZDRIfWZpclxHmTABcuJ6+kigUrU1m5P5+Qtr68cfNgLo3uKN0lwuFIgAuXUV1n4c1vD/Lqpiy0hvsm9OL/RvfAx1NmUQrHJAEunJ7WmnWpJ3h8RQqHiyuZ1LcTD0+JIqStLDolHJsEuHBqBwvKmbc8hW8yCojo0JoP7hjGyIh2ZpclhE1IgAunVF5TzysbMlmy+RA+Hu48MiWKW0eE4enuZnZpQtiMBLhwKlprvtxzlAWrUjlRVsNVg0N4aGIf2vt7m12aEDYnAS6cRvLRUuITktmRfZL+IQG8fvNgBoW2NbssIZqNBLhweCcranl2TTr/2X6YQD8vFl7Zj2viuuEmi04JJycBLhyWxar5cPthnluTTll1Pbf8Loz7LulFgK/MohSuQQJcOKTE7GIe+zKZlPxTDO8RRPz0GPp0amN2WUK0KAlw4VBOnKrmn1+l8d/deXQO8GHRDQOZ0q+zzKIULkkCXDiE2nor73x/iJfXZ1Jn0fxlbAR/GtsTPy95CwvXJe9+Yfe+yShg3vJkDhZUMCGqA49OjaZ7cCuzyxLCdE0OcKWUO5AI5Gmtpza9JCEMR4ormb8ihbUpxwkL9uOdWUMY26eD2WUJYTds0QK/B0gF5AySsImqWguvbcri9W8P4uGm+NvE3tx+UTjeHrLolBCna1KAK6VCgCnAk8BfbVKRcFlaa75KOsYTK1I4WlrN9Ngu/GNyFJ0CfMwuTQi71NQW+IvA3wD/cz1AKTUbmA0QGhraxM0JZ5VxvIz4hGS2HCiiTyd/Xrh2AMN6BJtdlhB2rdEBrpSaCpzQWu9USo051+O01m8CbwLExcXpxm5POKdT1XW8uDaTd3/IprW3B4/PiOH6oaF4yKJTQvymprTARwLTlVKTAR+gjVLq31rrm2xTmnBmVqvm0125PP11GkUVtVw/NJQHLu1NUCsvs0sTwmE0OsC11n8H/g7Q0AJ/QMJbnI+9R0qYm5DMniMlDAoNZOltQ+nbNcDssoRwODIOXLSYwvIanvk6nY93HiG4lTfPXR3LFQO7yqJTQjSSTQJca70J2GSL1xLOp95i5f2tOTy/NoOqWgt3XBTO3eMj8feRRaeEaAppgYtmteVAIfEJyWQcL2dUZDvmTosmosM5By0JIS6ABLhoFkdLqnhyVSor9+UT0taX128azGUxHWXRKSFsSAJc2FR1nYXFmw+xaEMWVq25d0IkfxzdEx9PmUUphK1JgAub0FqzPvUEj69MIaeokstiOvLIlGi6BfmZXZoQTksCXDTZwYJyHl+Rwsb0Anq2b8X7tw9lVGR7s8sSwulJgItGq6ip55UNWSzefBBvD3cemRLFrSPC8JRZlEK0CAlwccG01iTsPcqCVakcP1XDzEEhPDSpNx38ZdEpIVqSBLi4IClHTxGfkMz27GL6dQ3g1RsHM7h7W7PLEsIlSYCL81JSWcvzazP499YcAv28+OeV/bgmrhvuMotSCNNIgItfZbFqlu04wjOr0yitquPm4d356yW9CfCTWZRCmE0CXJzTzpyTzE1IIinvFEPDg5g3PYaoznLhJSHshQS4+IUTp6pZ+HUan+/Ko1MbH16+fiDT+neWWZRC2BkJcPGT2norS7cc4uX1WdTWW/nTmJ78eWwErbzlbSKEPZLfTAHAtxkFxC9P5mBBBeP6dOCxqdGEtWtldllCiF8hAe7ijhRX8sTKFFYnHycs2I/Ft8YxPqqj2WUJIc6DBLiLqq6z8NqmA7z+zQHclOLBy3pzx6hwvD1k0SkhHIUEuIvRWrM6+RiPr0glr6SKabFd+MfkPnQO8DW7NCHEBZIAdyFZJ8qIT0hhc1YhfTr5858/DOd3PYPNLksI0UgS4C6grLqOl9ZlsnRLNn5e7sRPi+am4d3xkEWnhHBoEuBOzGrVfL47j4VfpVFUUcO1cd148LLeBLf2Nrs0IYQNSIA7qf25pTyWkMTuwyUM6BbIkllx9A8JNLssIYQNSYA7maLyGp5Znc6yxCMEt/Limav6M3NQCG6y6JQQTkcC3EnUW6x8sO0wz61Jp7LWwu0jw7l7QiRtfGTRKSGclQS4E9h6sIj4hGTSjpVxUUQ74qdHE9HB3+yyhBDNTALcgeWXVrFgVRrL9x6la6Avr980iMtiOsmiU0K4CAlwB1RTb+Ht7w6xaEMWFq25e3wkd47uia+XzKIUwpVIgDuY9anHmb8ihZyiSi6N7sijU6PpFuRndllCCBM0OsCVUt2A94COgAbe1Fq/ZKvCxM8dKqxg/vJkNqYX0KN9K977/VAu7tXe7LKEECZqSgu8Hrhfa71LKeUP7FRKrdVap9ioNgFU1NSzaGMWi787hJeHGw9PjuLWEWF4ecgsSiFcXaMDXGudD+Q3fF+mlEoFugIS4DagtWb5vnwWrEzl2KlqrhzUlTkT+9ChjY/ZpQkh7IRN+sCVUmHAQGCbLV7P1aXmnyI+IZlth4rp27UN/7pxIIO7B5ldlhDCzjQ5wJVSrYHPgHu11qfO8vPZwGyA0NDQpm7OqZVW1vH82nTe35pDgK8nC67ox7VDuuEusyiFEGfRpABXSnlihPcHWuvPz/YYrfWbwJsAcXFxuinbc1YWq2bZjiM8szqN0qo6bhrenb9e0otAPy+zSxNC2LGmjEJRwGIgVWv9vO1Kci07c04Sn5DM/rxShoYFET89hugubcwuSwjhAJrSAh8J3AzsV0rtabjvH1rrVU2uygWcKKtm4VdpfL4rj45tvHnpugFMj+0isyiFEOetKaNQNgOSNheozmJl6ffZvLQ+k5p6C3eO6clfxkbQylvmVAkhLoykRgv6LrOA+IRkDhRUMKZ3e+ZOiyG8XSuzyxJCOCgJ8BZwpLiSJ1em8nXyMboH+7H41jjGR3U0uywhhIOTAG9G1XUWXv/mAK9tOoCbUjxwaS/uGNUDH09ZdEoI0XQS4M1Aa83q5OM8sTKF3JNVTOnfmYcnR9El0Nfs0oQQTkQC3MayTpQxb3kK32UW0rujPx/+YRgjerYzuywhhBOSALeRsuo6Xl6fyTvfZ+Pn5U78tGhuGt4dD3dZdEoI0TwkwJvIatX8d3ceC79Oo7C8hmvjuvHAZb1p19rb7NKEEE5OArwJkvJKeezLJHYdLmFAt0DeviWO2G6BZpclhHAREuCNUFxRyzOr0/lox2GCW3nxzFX9mTkoBDdZdEoI0YIkwC9AvcXKh9sP89yaDMpr6rltRDj3XhJJGx9Ps0sTQrggCfDztO1gEXMTkkk7VsaInsHET4+hV0d/s8sSQrgwCfDfcKy0mgWrUknYe5Sugb68euMgJvXtdH6LTlnqoLYcrFbQFlBu4OkHnr4gi1YJV2C1Qs0psNb/7z53L/BqDW4yQqupJMDPoabewuLNh1i0IYt6q+bucRHcOSYCX6/TZlFa6qAgHY4nQWEmlOTAyRwoOwZVJ6G27ByvrsCnDfh3Nr4CukJwJLTvA+17Q9swCXjhGKwWKD4EJ5LhRKrx/i89YnxVnjTCm7NdBkCBtz/4BUNACLTpCkHh0CEKOkRDUA9wkxnLv0UC/Cw2pp9g/vIUDhVWcEl0Rx6dEk1osB9UFsPBHyBni/F1PAkstcaTlLsRxIHdofsI8AsC37bg1QrcPIzWt9ZQVwG1FVBVAmX5xldGMlT8+38F+AZByBDjq8do6DII3OVQCTtQV2W89w//AIe3Qt5OqKts+KEyGiSB3aDrYGjVHnwCwLsNeDQMq9UaLDVQUwbVp6DiBJTmQfZ3sG8ZP4W9ZysIGQzdhkHocOg+0vjkKn5Gad1yF8mJi4vTiYmJLba9C5VTVMH85SmsTztBj/atmDs1mtGBhZDxFWSsgdztoK3g7g0hccabtFN/6NQPgnuCexNOZladhIIMoyWTuxPyEqEgzfiZdwCEj4Lek6H3JOOPgxAtpTQX0lZC5hrI3gz11UaDpFM/I2A7xxqt5vZ9wMuv8duprYTCdDieAvl74cg2OLbf6H708DFCPPISiJpmtNpdiFJqp9Y67hf3S4BDZW09/9qYxVvfHsLTXfHI77y52mc7Himf/y9EO8dC5GXQc6zRIvZsgavDVxbDoW/gwEbIWgen8oyWfvgo6Hc1RM8wPoYKYWtlxyHpM0j+r9FwAQiOgIhLIGIChA5rmfdeTbnR0j+w3vgdKMww7g8ZAtGXG78H/s6/sqcE+FlorVmxL58Fq1IpKS3h0fBMrnLbgFfeNkAZXSExV0CfqdCms9nFwtHdkJoAKV9C8UHjhGjUNBh0i9E6kX5z0RSWOqOVvfvfkLHaaPl26mcEZfTl0C7C7Aqh6ACkfAHJX8CxfUaDJvISGHgT9JrYtE/BdkwC/Axpx04Rn5DM0UOp3NdmE9OsG/CoK4OgnjDoZuh3jdGnbY+0htwdsOdDSPocakqNj69D7oDY66RVLi5MeQHsWgo7lkDZUWjdEWKvhwE3QvteZld3bgUZsOcD2PsRlB8D/y4Q93sYfCu07mB2dTYlAd6gtLKOF9ZlkLJtNXd6rmQMO8HNHRU9A+JuN1rdjtSSra2E5M9h+1uQv8foL4+bBcP+CG26mF2dsGcF6bDlZdj3sXEyvsdYGDobIi91rJPmlnrjk8OOt+DABmOYYv9rYMTdxqguJ+DyAW6xaj7ZcZgtq//DLfWfEeeWgdU3CLchtxt/tZ0h7HITYcsrRjeLcof+18KovxonWIX4Ue5O+O45SF8JHr4w4AbjD749t7bPV2EmbHsddn8A9VXQaxJc/IAx6MCBuXSA784pZsWn73B56Xv0c8umtnVXvEbdY/SbeTnhNSmLD8EP/4Ld7xstq35Xw8UPQrtIsysTZjqyHTYtNE4I+rY1WttDZ0MrJ1yvvqLIaJFve90Y4dVzPIyZA92Gml1Zo7hkgBecqua/n73PsEOvEut2kAq/bvhNeAgVe53Tnuz4mbLjxkfkxCXG0K/Y62H0Q9C2u9mViZaUvxfWzzdGcfgFw4i7YMgfwLu12ZU1v5oy2LHY+D2oLDJG0Ix7FLoMMLuyC+JSAV5nsfLV18vptP0phqpkSrw74zPh7/gMusE1gvtMFYWw+QWjn1xbYfAsI8hbtze7MtGcig7AhseNoYC+bWHkvcaJblcI7jPVVsCOt43fg6qTxqiacY/ax8ia8+AyAb5zdyIVKx/l4votlLoFUnvRg7S/eDZ4eDXrdh3CqaPwzdOw6z1jVtvIe+B3f3bObiRXVl4A3zwFO98xJp397k9Gq9snwOzKzFddanQv/vAvY1Zp3G0weo7dN2acPsCPHs0lbdmjjCr5kjrlydGYP9Bz+kMoGVL3S4WZsH4epC6H1p1g/KNG94qsPeHY6qqMYNr8ojG9ffAso9/XyYbU2UT5CeOPXOI7RmPmovuMxoydTtd32gCvrq5m27KnGXDwdVpTSWrny4m4dgE+bZ1gVElzO7wN1jxsjCnv1A8u+6cxy1M4Fq2NoaRr5xqLSPWeDBPmOceokuZWmGn8v6WvhIBuMCEe+s60u6HEThfgWmt2rf+Ydt/Po7vOI9UvjqArn6FjxCCbvL7L0NqYMr0u3vjlj5oOlz5urIgo7N/R3fDVHDiyFTr2g4kLIPxis6tyPIe+hdX/MNZe6TYMJj0FXQaaXdVPnCrAD2fupfizBxhQvZ0jbl0pv3geUaOvsru/mg6lrgq2LILNzxtLhI64yxhDLv3j9qm8wOgG2/1vYxjguEeNYbHSDdZ4Vosxs3P9fOPE/8CbYPxjdtEF1SwBrpSaCLwEuANva60X/trjmxrg5adOkvThwwzK/4ha5UVK5J0MvPohPL1aYGEpV1GaB+vmwv5PjDWaL5lvlx8pXZalzhhNtOmfRj/3sD/C6L/JCUpbqi6Fb5+Bra8bfeJj5hjj5U0cwWbzAFdKuQMZwCVALrADuF5rnXKu5zQ2wLXVys4VrxO26ynaUcKOwMn0uP5pgjt2a1Tt4jwc3gqrHjQWDOo+EiY9DZ36ml2Vazu4Cb56yFghs+d4mLhQ+rmbU2EmfD3HGD/frrfRrdJzrCmlnCvAm3JNo6FAltb6oNa6FvgImNGE1zunPc9OIW7X3yn26EDG9C8Zcu9/JLybW+hwmL0Jpr5gXGnljVFGoFcWm12Z6zmZA8tugvdmGBOyrvsP3PSZhHdzaxcJN34K139kXITi/cuN41By2OzKftKUFvhVwESt9R0Nt28Ghmmt/3LG42YDswFCQ0MH5+TkXPC2dnz5GlhqGTzjL7i5Sx9fi6ssho1PGjM6fQKNfsFBt0h/a3Orq4LvXzImn6Bg1P3GuYmWWIte/FxdNfzwCnz3vDEZ7qL7jHkULTTssDm6UM4rwE9nD6sRiiY4th9W/Q0ObzGuRDT5GaOlLmxLa2NBstWPQOlhY9bgpU8YlyoT5irNhTWPGsM2A0LhsieMkVvNfI6oObpQ8oDT31EhDfcJZ9WpH9y2Cq5aYqwrseQy+OwO48SnsI3jyfDedPj4FmNd91tXwDXvSnjbi4AQuPodmLXSuDD5x7fAu9PgWJIp5TSlBe6BcRJzPEZw7wBu0Fonn+s50gJ3IrUVxkf77182ulJG3mt8vG/KNRFdWUWh0U21c6lxEeBxj8Dg2xxrXW5XY6k3livY+KQxcmXwLBj7cLOs7thcwwgnAy9iDCNcorV+8tceLwHuhE7mwNpHjcu8tekK4+cay9e6NeXDnQupr4Ftb8C3z0JtubHY1Jg5cuFqR1JZbEzL3/4WeLWGi++Hof9n03MVTjWRR9ih7O+NmWz5e4wZbJc+AWEXmV2V/dLaWCVw3VxjVEPEBLj0SejQx+zKRGMVpMOaR4yrAwWGGtPyY660Sf+4BLhoflarMQFo/Tw4lWdcmmtCPHSMMbsy+3LwG2PpgqO7oEOMcSKs5zizqxK2cmCjEeTHk4zGzIR46DGmSS8pAS5aTl2V0S2w+XmoPmVcn3D0Q3Jpt7xdxvrcBzZAmxAY+3dZBdJZWS3GtUY3PmmsMdRzHEx5HoLCG/VyEuCi5VUW/+9CEpZaGHgjjHrA9a4IlL/PmPqevsq4sMKo+40r4sh4budXV21cSGL7G/CHjY0+wSkBLsxTdtxojScuMSZB9L/OmAjhIFdDabQjO4z9Tl9lrFUy4i7j5JZPG7MrEy3NamnSJy0JcGG+0jzY8oox9MpSa0yAGHGXw18x/GesVqOL5PsXIfs7o8U97E4Y/kdZcEo0mgS4sB/lJ4wrxyS+AzWl0G24EXB9pjruNUtrK2DfMtj6GhRmGFc6GnGXMTbYFa9BKWxKAlzYn5pyYz3rra9CSQ607ggDbzbWWXGUfvL8fcbkm/2fQM0p6DzAuDRX9OVyHVZhMxLgwn5ZLZC1HhIXQ8ZqQBtL2Pa/BqJnGN0Q9qQ0z7iK0f5PjOV2PXyMwI67zbiai6ydLmxMAlw4hpIjsO8j2LsMijLBzQPCRkHUVOg1CQK6tnxNWhvdIulfQcbXxlrpaOg6GPpfa/yhsbc/MsKpSIALx6K1MdEl5UtIXQHFB4z72/UyJkWEjTICtE0X27d4tYaT2UZQZ2+G7G//twZ0p/5GX32/q2Rcu2gxEuDCcWltTFPOWmtclSZni3E5MTBOFnYZYCy+364XBPUE/07G169dz1Nro8+6otAI65OHoOggHN8P+XuNxYnAaFl3H2lciaXXRGM1OiFa2LkCXJY6E/ZPKWONkA59jJEd9bVGyB7dZcxuzN9rDN2z1P78eZ5+Roh7+IKHN2iLcU3J+mqoKgFr3c8f7+EDHaIg5groHAshQ6FDtCzMJeyWBLhwPB5e0G2I8fUjq8Xo5ig+aAxTLD8OFQVGS72uyghtNw9w9zKGKvq2Bb924BdsLDwUFG605iWshQORABfOwc3dCOFGrjUhhCOS5oYQQjgoCXAhhHBQEuBCCOGgJMCFEMJBSYALIYSDkgAXQggHJQEuhBAOSgJcCCEcVIuuhaKUKgByGvn0dkChDctxFK643664z+Ca+y37fH66a63bn3lniwZ4UyilEs+2mIuzc8X9dsV9Btfcb9nnppEuFCGEcFAS4EII4aAcKcDfNLsAk7jifrviPoNr7rfscxM4TB+4EEKIn3OkFrgQQojTSIALIYSDcogAV0pNVEqlK6WylFJzzK6nOSiluimlNiqlUpRSyUqpexruD1JKrVVKZTb863SXP1dKuSuldiulVjTcDldKbWs43suUUl5m12hrSqlApdSnSqk0pVSqUup3zn6slVL3Nby3k5RS/1FK+TjjsVZKLVFKnVBKJZ1231mPrTK83LD/+5RSgy5kW3Yf4Eopd+BfwCQgGrheKRVtblXNoh64X2sdDQwH/tywn3OA9VrrSGB9w21ncw+Qetrtp4AXtNYRwEngdlOqal4vAV9rrfsAsRj777THWinVFbgbiNNa9wXcgetwzmO9FJh4xn3nOraTgMiGr9nAaxeyIbsPcGAokKW1Pqi1rgU+AmaYXJPNaa3ztda7Gr4vw/iF7oqxr+82POxd4HJTCmwmSqkQYArwdsNtBYwDPm14iDPucwBwMbAYQGtdq7UuwcmPNcYlHH2VUh6AH5CPEx5rrfW3QPEZd5/r2M4A3tOGrUCgUqrz+W7LEQK8K3DktNu5Dfc5LaVUGDAQ2AZ01FrnN/zoGNDRrLqayYvA3wBrw+1goERrXd9w2xmPdzhQALzT0HX0tlKqFU58rLXWecCzwGGM4C4FduL8x/pH5zq2Tco3Rwhwl6KUag18BtyrtT51+s+0MebTacZ9KqWmAie01jvNrqWFeQCDgNe01gOBCs7oLnHCY90Wo7UZDnQBWvHLbgaXYMtj6wgBngd0O+12SMN9Tkcp5YkR3h9orT9vuPv4jx+pGv49YVZ9zWAkMF0plY3RNTYOo284sOFjNjjn8c4FcrXW2xpuf4oR6M58rCcAh7TWBVrrOuBzjOPv7Mf6R+c6tk3KN0cI8B1AZMPZai+MEx8JJtdkcw19v4uBVK3186f9KAG4teH7W4EvW7q25qK1/rvWOkRrHYZxXDdorW8ENgJXNTzMqfYZQGt9DDiilOrdcNd4IAUnPtYYXSfDlVJ+De/1H/fZqY/1ac51bBOAWxpGowwHSk/ravltWmu7/wImAxnAAeBhs+tppn28CONj1T5gT8PXZIw+4fVAJrAOCDK71mba/zHAiobvewDbgSzgE8Db7PqaYX8HAIkNx/sLoK2zH2tgHpAGJAHvA97OeKyB/2D089dhfNq6/VzHFlAYo+wOAPsxRumc97ZkKr0QQjgoR+hCEUIIcRYS4EII4aAkwIUQwkFJgAshhIOSABdCCAclAS6EEA5KAlwIIRzU/wOkbX6URZiiTQAAAABJRU5ErkJggg==\n" + "text/plain": "
" }, "metadata": { "needs_background": "light" - } + }, + "output_type": "display_data" } + ], + "source": [ + "ax = df.plot()" ] } - ] + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.8.3 64-bit ('base': conda)", + "metadata": { + "interpreter": { + "hash": "61a9efb557ee20b19fda2d58cb63f9a3bf86c2530fcd43d63aa6e0adea42a5e4" + } + }, + "name": "Python 3.8.3 64-bit ('base': conda)" + }, + "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.8.3-final" + }, + "orig_nbformat": 2 + }, + "nbformat": 4, + "nbformat_minor": 2 } \ No newline at end of file diff --git a/tests/test_builds.py b/tests/test_builds.py index ef4c851..8d70149 100644 --- a/tests/test_builds.py +++ b/tests/test_builds.py @@ -13,6 +13,7 @@ # standard lib import logging import os +import sys import re import shutil from contextlib import contextmanager @@ -44,6 +45,7 @@ # ########## Helpers ############### # ################################## + @contextmanager def working_directory(path): """ @@ -77,14 +79,9 @@ def get_plugin_config_from_mkdocs(mkdocs_path) -> dict: logging.info("Fixture configuration loaded: " + str(cfg)) if plugin_loaded.config.get("enabled"): - assert ( - plugin_loaded.config.get("locale") is not None - ), "Locale should never be None after plugin is loaded" + assert plugin_loaded.config.get("locale") is not None, "Locale should never be None after plugin is loaded" - logging.info( - "Locale '%s' determined from %s" - % (plugin_loaded.config.get("locale"), mkdocs_path) - ) + logging.info("Locale '%s' determined from %s" % (plugin_loaded.config.get("locale"), mkdocs_path)) return plugin_loaded.config @@ -121,12 +118,18 @@ def setup_clean_mkdocs_folder(mkdocs_yml_path, output_path): shutil.copytree("tests/fixtures/i18n/docs", str(testproject_path / "docs")) else: shutil.copytree("tests/fixtures/basic_project/docs", str(testproject_path / "docs")) - + + shutil.copyfile("tests/fixtures/basic_project/gen_files.py", str(testproject_path / "gen_files.py")) shutil.copyfile(mkdocs_yml_path, str(testproject_path / "mkdocs.yml")) + if "gen-files" in mkdocs_yml_path: shutil.copyfile(str(Path(mkdocs_yml_path).parent / "gen_pages.py"), str(testproject_path / "gen_pages.py")) + # Copy monorepo files + if "monorepo" in mkdocs_yml_path: + shutil.copytree("tests/fixtures/monorepo", str(testproject_path), dirs_exist_ok=True) + return testproject_path @@ -144,60 +147,80 @@ def setup_commit_history(testproject_path): Returns: repo (repo): git.Repo object """ - assert not os.path.exists(str(testproject_path / ".git")) - testproject_path = str(testproject_path) + assert not (testproject_path / ".git").exists() repo = git.Repo.init(testproject_path, bare=False) repo.git.checkout("-b", "master") author = "Test Person " - with working_directory(testproject_path): - # page_with_tags contains tags we replace and test if os.path.exists("docs/page_with_tag.md"): repo.git.add("docs/page_with_tag.md") - repo.git.commit(message="add homepage", author=author, date="1500854705") # Mon Jul 24 2017 00:05:05 GMT+0000 + repo.git.commit( + message="add homepage", author=author, date="1500854705" + ) # Mon Jul 24 2017 00:05:05 GMT+0000 + + file_name = testproject_path / "docs/page_with_tag.md" + with open(file_name, "a") as the_file: + the_file.write("test\n") + repo.git.add("docs/page_with_tag.md") + repo.git.commit( + message="update homepage #1", author=author, date="1525475836" + ) # Fri May 04 2018 23:17:16 GMT+0000 - file_name = os.path.join(testproject_path, "docs/page_with_tag.md") with open(file_name, "a") as the_file: the_file.write("awa\n") repo.git.add("docs/page_with_tag.md") - repo.git.commit(message="update homepage", author=author, date="1642911026") # Sun Jan 23 2022 04:10:26 GMT+0000 + repo.git.commit( + message="update homepage #2", author=author, date="1642911026" + ) # Sun Jan 23 2022 04:10:26 GMT+0000 if os.path.exists("docs/page_with_renamed.md"): - bf_file_name = os.path.join(testproject_path, "docs/page_with_renamed.md") - af_file_name = os.path.join(testproject_path, "docs/subfolder/page_with_renamed.md") + bf_file_name = testproject_path / "docs/page_with_renamed.md" + af_file_name = testproject_path / "docs/subfolder/page_with_renamed.md" # Since git.mv would actually remove the file, move page_with_renamed.md back to docs if it has been moved - if os.path.exists(af_file_name): + if af_file_name.exists(): os.replace(af_file_name, bf_file_name) repo.git.add("docs/page_with_renamed.md") - repo.git.commit(message="page_with_renamed.md before renamed", author=author, date="1655229469") # Tue Jun 14 2022 17:57:49 GMT+0000 + repo.git.commit( + message="page_with_renamed.md before renamed", author=author, date="1655229469" + ) # Tue Jun 14 2022 17:57:49 GMT+0000 repo.git.mv("docs/page_with_renamed.md", "docs/subfolder/page_with_renamed.md") - repo.git.commit(message="page_with_renamed.md after renamed", author=author, date="1655229515") # Tue Jun 14 2022 17:58:35 GMT+0000 + repo.git.commit( + message="page_with_renamed.md after renamed", author=author, date="1655229515" + ) # Tue Jun 14 2022 17:58:35 GMT+0000 if os.path.exists("docs/first_page.md"): repo.git.add("docs/first_page.md") - repo.git.commit(message="first page", author=author, date="1500854705") # Mon Jul 24 2017 00:05:05 GMT+0000 - file_name = os.path.join(testproject_path, "docs/first_page.md") + repo.git.commit(message="first page", author=author, date="1500854705") # Mon Jul 24 2017 00:05:05 GMT+0000 + file_name = testproject_path / "docs/first_page.md" with open(file_name, "w+") as the_file: the_file.write("Hello\n") repo.git.add("docs/first_page.md") - repo.git.commit(message="first page update 1", author=author, date="1519964705") # Fri Mar 02 2018 04:25:05 GMT+0000 + repo.git.commit( + message="first page update 1", author=author, date="1519964705" + ) # Fri Mar 02 2018 04:25:05 GMT+0000 with open(file_name, "w") as the_file: the_file.write("# First Test Page Edited\n\nSome Lorem text") repo.git.add("docs/first_page.md") - repo.git.commit(message="first page update 2", author=author, date="1643911026") # Thu Feb 03 2022 17:57:06 GMT+0000 + repo.git.commit( + message="first page update 2", author=author, date="1643911026" + ) # Thu Feb 03 2022 17:57:06 GMT+0000 repo.git.add("mkdocs.yml") - repo.git.commit(message="add mkdocs", author=author, date="1500854705 -0700") # Mon Jul 24 2017 00:05:05 GMT+0000 + repo.git.commit( + message="add mkdocs", author=author, date="1500854705 -0700" + ) # Mon Jul 24 2017 00:05:05 GMT+0000 - if os.path.exists("docs/second_page.md"): + if Path("docs/second_page.md").exists(): repo.git.add("docs/second_page.md") - repo.git.commit(message="second page", author=author, date="1643911026") # Thu Feb 03 2022 17:57:06 GMT+0000 - + repo.git.commit( + message="second page", author=author, date="1643911026" + ) # Thu Feb 03 2022 17:57:06 GMT+0000 + repo.git.add("docs/index.md") - repo.git.commit(message="homepage", author=author, date="1643911026") # Thu Feb 03 2022 17:57:06 GMT+0000 + repo.git.commit(message="homepage", author=author, date="1643911026") # Thu Feb 03 2022 17:57:06 GMT+0000 return repo @@ -242,20 +265,21 @@ def validate_build(testproject_path, plugin_config: dict = {}): # Make sure with markdown tag has valid # git revision date tag - if not plugin_config.get('enabled'): - return - + if not plugin_config.get("enabled"): + return + page_with_tag = testproject_path / "site/page_with_tag/index.html" contents = page_with_tag.read_text(encoding="utf8") assert re.search(r"renders as\:\s[|\w].+", contents) - repo = Util(config=plugin_config) + repo = Util(config=plugin_config, mkdocs_dir=testproject_path) + commit_hash, commit_timestamp = repo.get_git_commit_timestamp( + path=str(testproject_path / "docs/page_with_tag.md"), + is_first_commit=False, + ) date_formats = repo.get_date_formats_for_timestamp( - commit_timestamp=repo.get_git_commit_timestamp( - path=str(testproject_path / "docs/page_with_tag.md"), - is_first_commit=False, - ), - locale=plugin_config['locale'], + commit_timestamp, + locale=plugin_config["locale"], add_spans=True, ) @@ -263,14 +287,14 @@ def validate_build(testproject_path, plugin_config: dict = {}): assert any(searches), "No correct revision date formats output was found" if plugin_config.get("enable_creation_date"): - commit_timestamp=repo.get_git_commit_timestamp( + commit_hash, commit_timestamp = repo.get_git_commit_timestamp( path=str(testproject_path / "docs/page_with_tag.md"), is_first_commit=True, ) assert commit_timestamp == 1500854705 date_formats = repo.get_date_formats_for_timestamp( commit_timestamp=commit_timestamp, - locale=plugin_config['locale'], + locale=plugin_config["locale"], add_spans=True, ) @@ -278,12 +302,12 @@ def validate_build(testproject_path, plugin_config: dict = {}): assert any(searches), "No correct creation date formats output was found" if os.path.exists(str(testproject_path / "docs/subfolder/page_with_renamed.md")): - commit_timestamp=repo.get_git_commit_timestamp( - path=str(testproject_path / "docs/subfolder/page_with_renamed.md"), - is_first_commit=True + commit_hash, commit_timestamp = repo.get_git_commit_timestamp( + path=str(testproject_path / "docs/subfolder/page_with_renamed.md"), is_first_commit=True ) assert commit_timestamp == 1655229469 + def validate_mkdocs_file(temp_path: str, mkdocs_yml_file: str): """ Creates a clean mkdocs project @@ -293,50 +317,47 @@ def validate_mkdocs_file(temp_path: str, mkdocs_yml_file: str): temp_path (PosixPath): Path to temporary folder mkdocs_yml_file (PosixPath): Path to mkdocs.yml file """ - testproject_path = setup_clean_mkdocs_folder( - mkdocs_yml_path=mkdocs_yml_file, output_path=temp_path - ) + testproject_path = setup_clean_mkdocs_folder(mkdocs_yml_path=mkdocs_yml_file, output_path=temp_path) setup_commit_history(testproject_path) result = build_docs_setup(testproject_path) - assert result.exit_code == 0, "'mkdocs build' command failed" + assert result.exit_code == 0, f"'mkdocs build' command failed with output:\n{result.stdout}" # validate build with locale retrieved from mkdocs config file - validate_build( - testproject_path, plugin_config=get_plugin_config_from_mkdocs(mkdocs_yml_file) - ) + validate_build(testproject_path, plugin_config=get_plugin_config_from_mkdocs(mkdocs_yml_file)) return testproject_path - MKDOCS_FILES = [ - 'basic_project/mkdocs_theme_no_locale.yml', - 'basic_project/mkdocs.yml', - 'basic_project/mkdocs_theme_timeago_locale.yml', - 'basic_project/mkdocs_datetime.yml', - 'basic_project/mkdocs_plugin_locale.yml', - 'basic_project/mkdocs_with_override.yml', - 'basic_project/mkdocs_theme_language.yml', - 'basic_project/mkdocs_theme_locale_and_language.yml', - 'basic_project/mkdocs_theme_locale_disabled.yml', - 'basic_project/mkdocs_theme_timeago.yml', - 'basic_project/mkdocs_theme_locale.yml', - 'basic_project/mkdocs_theme_timeago_override.yml', - 'basic_project/mkdocs_theme_timeago_instant.yml', - 'basic_project/mkdocs_creation_date.yml', - 'basic_project/mkdocs_timeago_locale.yml', - 'basic_project/mkdocs_timeago.yml', - 'basic_project/mkdocs_fallback_to_build_date.yml', - 'basic_project/mkdocs_locale.yml', - 'basic_project/mkdocs_exclude.yml', - 'basic_project/mkdocs_meta.yml', - 'basic_project/mkdocs_custom_type.yml', + "basic_project/mkdocs_creation_date.yml", + "basic_project/mkdocs_custom_type.yml", + "basic_project/mkdocs_datetime.yml", + "basic_project/mkdocs_exclude.yml", + "basic_project/mkdocs_fallback_to_build_date.yml", + "basic_project/mkdocs_locale.yml", + "basic_project/mkdocs_meta.yml", + "basic_project/mkdocs_no_parallel.yml", + "basic_project/mkdocs_plugin_locale.yml", + "basic_project/mkdocs.yml", + "basic_project/mkdocs_theme_timeago_locale.yml", + "basic_project/mkdocs_theme_language.yml", + "basic_project/mkdocs_theme_locale_and_language.yml", + "basic_project/mkdocs_theme_locale_disabled.yml", + "basic_project/mkdocs_theme_timeago.yml", + "basic_project/mkdocs_theme_locale.yml", + "basic_project/mkdocs_theme_no_locale.yml", + "basic_project/mkdocs_theme_timeago_override.yml", + "basic_project/mkdocs_theme_timeago_instant.yml", + "basic_project/mkdocs_timeago_locale.yml", + "basic_project/mkdocs_timeago.yml", + "basic_project/mkdocs_with_override.yml", + "techdocs-core/mkdocs.yml", # 'i18n/mkdocs.yml' ] INVALID_MKDOCS_FILES = [ - ('basic_project/mkdocs_unknown_type.yml', "AssertionError"), - ('i18n/mkdocs_wrong_order.yml', "should be defined after the i18n plugin in your mkdocs.yml"), + ("basic_project/mkdocs_unknown_type.yml", "AssertionError"), + ("i18n/mkdocs_wrong_order.yml", "should be defined after the i18n plugin in your mkdocs.yml"), ] @@ -350,90 +371,82 @@ def test_tags_are_replaced(tmp_path, mkdocs_file): """ Make sure the {{ }} tags are replaced properly. """ - testproject_path = setup_clean_mkdocs_folder( - mkdocs_yml_path=f"tests/fixtures/{mkdocs_file}", output_path=tmp_path - ) + if sys.platform.startswith("win") and ("monorepo" in mkdocs_file or "techdocs" in mkdocs_file): + pytest.skip("monorepo plugin windows issue (even without this plugin)") + testproject_path = setup_clean_mkdocs_folder(mkdocs_yml_path=f"tests/fixtures/{mkdocs_file}", output_path=tmp_path) setup_commit_history(testproject_path) result = build_docs_setup(testproject_path) assert result.exit_code == 0, "'mkdocs build' command failed" - plugin_config=get_plugin_config_from_mkdocs(str(testproject_path / "mkdocs.yml")) + plugin_config = get_plugin_config_from_mkdocs(str(testproject_path / "mkdocs.yml")) tags_file = testproject_path / "site/page_with_tag/index.html" contents = tags_file.read_text(encoding="utf8") # validate the build - validate_build( - testproject_path, plugin_config=plugin_config - ) + validate_build(testproject_path, plugin_config=plugin_config) if plugin_config.get("enabled") == False: return True if plugin_config.get("type") == "timeago": - pytest.skip("Not necessary to test the JS library") + pytest.skip("Not necessary to test the JS library") # Make sure count_commits() works - # We created 10 commits in setup_commit_history() + # We created 11 commits in setup_commit_history() with working_directory(testproject_path): - u = Util() - assert commit_count(u._get_repo("docs/page_with_tag.md")) == 10 + u = Util(config={}, mkdocs_dir=os.getcwd()) + assert commit_count(u._get_repo("docs/page_with_tag.md")) == 11 - # the revision date was in 'setup_commit_history' was set to 1642911026 (Sun Jan 23 2022 04:10:26 GMT+0000) # Assert {{ git_revision_date_localized }} is replaced - date_formats_revision_date = get_date_formats(1642911026, + date_formats_revision_date = get_date_formats( + 1642911026, locale=plugin_config.get("locale"), time_zone=plugin_config.get("timezone"), - custom_format=plugin_config.get("custom_format") + custom_format=plugin_config.get("custom_format"), ) for k, v in date_formats_revision_date.items(): assert v is not None - - date = date_formats_revision_date.get(plugin_config.get('type')) + + date = date_formats_revision_date.get(plugin_config.get("type")) assert re.search(rf"{date}\<\/span.+", contents) # The last site revision was set in setup_commit_history to 1643911026 (Thu Feb 03 2022 17:57:06 GMT+0000) # Assert {{ git_site_revision_date_localized }} is replaced - date_formats_revision_date = get_date_formats(1643911026, + date_formats_revision_date = get_date_formats( + 1643911026, locale=plugin_config.get("locale"), time_zone=plugin_config.get("timezone"), - custom_format=plugin_config.get("custom_format") + custom_format=plugin_config.get("custom_format"), ) for k, v in date_formats_revision_date.items(): assert v is not None - date = date_formats_revision_date.get(plugin_config.get('type')) + date = date_formats_revision_date.get(plugin_config.get("type")) assert re.search(rf"{date}\<\/span.+", contents) # Note {{ git_creation_date_localized }} is only replaced when configured in the config if plugin_config.get("enable_creation_date"): # The creation of page_with_tag.md was set in setup_commit_history to 1500854705 ( Mon Jul 24 2017 00:05:05 GMT+0000 ) - date_formats_revision_date = get_date_formats(1500854705, + date_formats_revision_date = get_date_formats( + 1500854705, locale=plugin_config.get("locale"), time_zone=plugin_config.get("timezone"), - custom_format=plugin_config.get("custom_format") + custom_format=plugin_config.get("custom_format"), ) for k, v in date_formats_revision_date.items(): assert v is not None - date = date_formats_revision_date.get(plugin_config.get('type')) + date = date_formats_revision_date.get(plugin_config.get("type")) assert re.search(rf"{date}\<\/span.+", contents) - - - - def test_git_not_available(tmp_path, recwarn): """ When there is no GIT repo, this should fail """ - testproject_path = setup_clean_mkdocs_folder( - "tests/fixtures/basic_project/mkdocs.yml", tmp_path - ) + testproject_path = setup_clean_mkdocs_folder("tests/fixtures/basic_project/mkdocs.yml", tmp_path) result = build_docs_setup(testproject_path) - assert ( - result.exit_code == 1 - ), "'mkdocs build' command succeeded while there is no GIT repo" + assert result.exit_code == 1, "'mkdocs build' command succeeded while there is no GIT repo" # assert there's a no error when fallback to build date is set to true testproject_path = setup_clean_mkdocs_folder( @@ -443,16 +456,12 @@ def test_git_not_available(tmp_path, recwarn): assert result.exit_code == 0 - - def test_build_material_theme(tmp_path): """ When using mkdocs-material theme, test correct working """ # theme set to 'material' with 'language' set to 'de' - testproject_path = validate_mkdocs_file( - tmp_path, "tests/fixtures/basic_project/mkdocs_theme_language.yml" - ) + testproject_path = validate_mkdocs_file(tmp_path, "tests/fixtures/basic_project/mkdocs_theme_language.yml") # In mkdocs-material, a 'last update' should appear # in German because locale is set to 'de' @@ -466,9 +475,7 @@ def test_material_theme_locale(tmp_path): When using mkdocs-material theme, test correct working """ # theme set to 'material' with 'locale' set to 'de' - testproject_path = validate_mkdocs_file( - tmp_path, "tests/fixtures/basic_project/mkdocs_theme_locale.yml" - ) + testproject_path = validate_mkdocs_file(tmp_path, "tests/fixtures/basic_project/mkdocs_theme_locale.yml") # In mkdocs-material, a 'last update' should appear # in english instead of German because you should use 'language' and not locale. @@ -483,9 +490,7 @@ def test_material_theme_locale_disabled(tmp_path): When using mkdocs-material theme, test correct working """ # theme set to 'material' with 'locale' set to 'de' - testproject_path = validate_mkdocs_file( - tmp_path, "tests/fixtures/basic_project/mkdocs_theme_locale_disabled.yml" - ) + testproject_path = validate_mkdocs_file(tmp_path, "tests/fixtures/basic_project/mkdocs_theme_locale_disabled.yml") # In mkdocs-material, a 'last update' should appear # in english instead of German because you should use 'language' and not locale. @@ -500,9 +505,7 @@ def test_material_theme_no_locale(tmp_path): When using mkdocs-material theme, test correct working """ # theme set to 'material' with 'language' set to 'de' - testproject_path = validate_mkdocs_file( - tmp_path, "tests/fixtures/basic_project/mkdocs_theme_no_locale.yml" - ) + testproject_path = validate_mkdocs_file(tmp_path, "tests/fixtures/basic_project/mkdocs_theme_no_locale.yml") # In mkdocs-material, a 'last update' should appear # in english because default locale is set to 'en' @@ -511,15 +514,14 @@ def test_material_theme_no_locale(tmp_path): assert re.search(r"Last update", contents) - @pytest.mark.parametrize("mkdocs_file, error", INVALID_MKDOCS_FILES) def test_type_unknown(mkdocs_file, error, tmp_path): """ Make sure invalid mkdocs.yml specification raise the correct errors. """ testproject_path = setup_clean_mkdocs_folder( - mkdocs_yml_path=f"tests/fixtures/{ mkdocs_file }", # mkdocs_file, # tmp_path, , - output_path=tmp_path + mkdocs_yml_path=f"tests/fixtures/{mkdocs_file}", # mkdocs_file, # tmp_path, , + output_path=tmp_path, ) # Setup git commit history assert not os.path.exists(str(testproject_path / ".git")) @@ -531,7 +533,7 @@ def test_type_unknown(mkdocs_file, error, tmp_path): with working_directory(testproject_path): # page_with_tags contains tags we replace and test repo.git.add(".") - repo.git.commit(message="add all", author=author, date="1500854705") # Mon Jul 24 2017 00:05:05 GMT+0000 + repo.git.commit(message="add all", author=author, date="1500854705") # Mon Jul 24 2017 00:05:05 GMT+0000 result = build_docs_setup(testproject_path) assert result.exit_code == 1 @@ -539,16 +541,12 @@ def test_type_unknown(mkdocs_file, error, tmp_path): assert error in result.stdout or error in str(result.exc_info[0]) - - def test_exclude_pages(tmp_path): """ When using mkdocs-material theme, test correct working """ # theme set to 'material' with 'locale' set to 'de' - testproject_path = validate_mkdocs_file( - tmp_path, "tests/fixtures/basic_project/mkdocs_exclude.yml" - ) + testproject_path = validate_mkdocs_file(tmp_path, "tests/fixtures/basic_project/mkdocs_exclude.yml") # Make sure revision date does not exist in excluded pages first_page = testproject_path / "site/first_page/index.html" @@ -560,16 +558,13 @@ def test_exclude_pages(tmp_path): assert not re.search(r"Last update\:\s[', - "custom": "01. January 1970" + "custom": "01. January 1970", } assert get_date_formats(0) == expected_output + # Test with 4-letter locale + new_expected_output = expected_output.copy() + new_expected_output["timeago"] = '' + assert get_date_formats(0, locale="en_US") == new_expected_output + + # Test with different locale + expected_output = { + "date": "1 janvier 1970", + "datetime": "1 janvier 1970 00:00:00", + "iso_date": "1970-01-01", + "iso_datetime": "1970-01-01 00:00:00", + "timeago": '', + "custom": "01. janvier 1970", + } + assert get_date_formats(0, locale="fr") == expected_output + + # Test with pt_BR locale + expected_output = { + "date": "1 de janeiro de 1970", + "datetime": "1 de janeiro de 1970 00:00:00", + "iso_date": "1970-01-01", + "iso_datetime": "1970-01-01 00:00:00", + "timeago": '', + "custom": "01. janeiro 1970", + } + assert get_date_formats(0, locale="pt_BR") == expected_output + + # Test with non-existing locale + with pytest.raises(UnknownLocaleError): + get_date_formats(0, locale="abcd") + # Test with custom arguments expected_output = { "date": "January 1, 1970", @@ -25,7 +55,7 @@ def test_get_dates(): "iso_date": "1970-01-01", "iso_datetime": "1970-01-01 00:00:00", "timeago": '', - "custom": "01. Jan 1970" + "custom": "01. Jan 1970", } assert get_date_formats(0, locale="en", time_zone="UTC", custom_format="%d. %b %Y") == expected_output @@ -36,7 +66,7 @@ def test_get_dates(): "iso_date": "1970-01-01", "iso_datetime": "1970-01-01 02:00:00", "timeago": '', - "custom": "01. January 1970" + "custom": "01. January 1970", } loc_dt = datetime(1970, 1, 1, 1, 0, 0, tzinfo=get_timezone("Europe/Berlin")) unix_timestamp = loc_dt.replace(tzinfo=timezone.utc).timestamp() @@ -44,7 +74,7 @@ def test_get_dates(): # Test with missing arguments with pytest.raises(TypeError): - get_date_formats() # noqa + get_date_formats() # noqa # Test with invalid timezone with pytest.raises(LookupError): @@ -52,21 +82,20 @@ def test_get_dates(): # Test with more recent date expected_output = { - 'date': 'October 15, 2023', - 'datetime': 'October 15, 2023 13:32:04', - 'iso_date': '2023-10-15', - 'iso_datetime': '2023-10-15 13:32:04', - 'timeago': '', - 'custom': '15. October 2023' + "date": "October 15, 2023", + "datetime": "October 15, 2023 13:32:04", + "iso_date": "2023-10-15", + "iso_datetime": "2023-10-15 13:32:04", + "timeago": '', + "custom": "15. October 2023", } assert get_date_formats(1697369524, time_zone="Europe/Amsterdam") == expected_output - assert get_date_formats(1582397529) == { "date": "February 22, 2020", "datetime": "February 22, 2020 18:52:09", "iso_date": "2020-02-22", "iso_datetime": "2020-02-22 18:52:09", "timeago": '', - "custom": '22. February 2020', - } \ No newline at end of file + "custom": "22. February 2020", + } diff --git a/tests/test_exclude.py b/tests/test_exclude.py index dd19cc9..7f87d3b 100644 --- a/tests/test_exclude.py +++ b/tests/test_exclude.py @@ -1,8 +1,8 @@ from mkdocs_git_revision_date_localized_plugin.exclude import exclude import pytest -def test_exclude(): +def test_exclude(): with pytest.raises(AssertionError): exclude("fsdfs", "not a list") @@ -16,4 +16,4 @@ def test_exclude(): globs = ["folder/*"] assert exclude("folder/index.md", globs) - assert not exclude("subfolder/index.md", globs) \ No newline at end of file + assert not exclude("subfolder/index.md", globs) diff --git a/tests/test_parse_git_ignore_revs.py b/tests/test_parse_git_ignore_revs.py new file mode 100644 index 0000000..7ada34a --- /dev/null +++ b/tests/test_parse_git_ignore_revs.py @@ -0,0 +1,21 @@ +from mkdocs_git_revision_date_localized_plugin.util import Util +import pytest +import tempfile +import os + +TEST_PARAMS = [ + ("abc123\n", ["abc123"]), + ("abc123 # comments are ignored\n", ["abc123"]), + ("\n\n\n\n\nabc123\n\n\n\n\n", ["abc123"]), +] + + +@pytest.mark.parametrize("test_input,expected", TEST_PARAMS) +def test_parse_git_ignore_revs(test_input, expected): + with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", delete=False) as fp: + fp.write(test_input) + temp_file_name = fp.name + try: + assert Util.parse_git_ignore_revs(temp_file_name) == expected + finally: + os.remove(temp_file_name) diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..951682f --- /dev/null +++ b/uv.lock @@ -0,0 +1,1254 @@ +version = 1 +revision = 1 +requires-python = ">=3.8" +resolution-markers = [ + "python_full_version >= '3.9'", + "python_full_version < '3.9'", +] + +[[package]] +name = "babel" +version = "2.17.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytz", marker = "python_full_version < '3.9'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537 }, +] + +[[package]] +name = "backrefs" +version = "5.7.post1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.9'", +] +sdist = { url = "https://files.pythonhosted.org/packages/df/30/903f35159c87ff1d92aa3fcf8cb52de97632a21e0ae43ed940f5d033e01a/backrefs-5.7.post1.tar.gz", hash = "sha256:8b0f83b770332ee2f1c8244f4e03c77d127a0fa529328e6a0e77fa25bee99678", size = 6582270 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/bb/47fc255d1060dcfd55b460236380edd8ebfc5b2a42a0799ca90c9fc983e3/backrefs-5.7.post1-py310-none-any.whl", hash = "sha256:c5e3fd8fd185607a7cb1fefe878cfb09c34c0be3c18328f12c574245f1c0287e", size = 380429 }, + { url = "https://files.pythonhosted.org/packages/89/72/39ef491caef3abae945f5a5fd72830d3b596bfac0630508629283585e213/backrefs-5.7.post1-py311-none-any.whl", hash = "sha256:712ea7e494c5bf3291156e28954dd96d04dc44681d0e5c030adf2623d5606d51", size = 392234 }, + { url = "https://files.pythonhosted.org/packages/6a/00/33403f581b732ca70fdebab558e8bbb426a29c34e0c3ed674a479b74beea/backrefs-5.7.post1-py312-none-any.whl", hash = "sha256:a6142201c8293e75bce7577ac29e1a9438c12e730d73a59efdd1b75528d1a6c5", size = 398110 }, + { url = "https://files.pythonhosted.org/packages/5d/ea/df0ac74a26838f6588aa012d5d801831448b87d0a7d0aefbbfabbe894870/backrefs-5.7.post1-py38-none-any.whl", hash = "sha256:ec61b1ee0a4bfa24267f6b67d0f8c5ffdc8e0d7dc2f18a2685fd1d8d9187054a", size = 369477 }, + { url = "https://files.pythonhosted.org/packages/6f/e8/e43f535c0a17a695e5768670fc855a0e5d52dc0d4135b3915bfa355f65ac/backrefs-5.7.post1-py39-none-any.whl", hash = "sha256:05c04af2bf752bb9a6c9dcebb2aff2fab372d3d9d311f2a138540e307756bd3a", size = 380429 }, +] + +[[package]] +name = "backrefs" +version = "5.8" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.9'", +] +sdist = { url = "https://files.pythonhosted.org/packages/6c/46/caba1eb32fa5784428ab401a5487f73db4104590ecd939ed9daaf18b47e0/backrefs-5.8.tar.gz", hash = "sha256:2cab642a205ce966af3dd4b38ee36009b31fa9502a35fd61d59ccc116e40a6bd", size = 6773994 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/cb/d019ab87fe70e0fe3946196d50d6a4428623dc0c38a6669c8cae0320fbf3/backrefs-5.8-py310-none-any.whl", hash = "sha256:c67f6638a34a5b8730812f5101376f9d41dc38c43f1fdc35cb54700f6ed4465d", size = 380337 }, + { url = "https://files.pythonhosted.org/packages/a9/86/abd17f50ee21b2248075cb6924c6e7f9d23b4925ca64ec660e869c2633f1/backrefs-5.8-py311-none-any.whl", hash = "sha256:2e1c15e4af0e12e45c8701bd5da0902d326b2e200cafcd25e49d9f06d44bb61b", size = 392142 }, + { url = "https://files.pythonhosted.org/packages/b3/04/7b415bd75c8ab3268cc138c76fa648c19495fcc7d155508a0e62f3f82308/backrefs-5.8-py312-none-any.whl", hash = "sha256:bbef7169a33811080d67cdf1538c8289f76f0942ff971222a16034da88a73486", size = 398021 }, + { url = "https://files.pythonhosted.org/packages/04/b8/60dcfb90eb03a06e883a92abbc2ab95c71f0d8c9dd0af76ab1d5ce0b1402/backrefs-5.8-py313-none-any.whl", hash = "sha256:e3a63b073867dbefd0536425f43db618578528e3896fb77be7141328642a1585", size = 399915 }, + { url = "https://files.pythonhosted.org/packages/0c/37/fb6973edeb700f6e3d6ff222400602ab1830446c25c7b4676d8de93e65b8/backrefs-5.8-py39-none-any.whl", hash = "sha256:a66851e4533fb5b371aa0628e1fee1af05135616b86140c9d787a2ffdf4b8fdc", size = 380336 }, +] + +[[package]] +name = "certifi" +version = "2025.1.31" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/58/5580c1716040bc89206c77d8f74418caf82ce519aae06450393ca73475d1/charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", size = 198013 }, + { url = "https://files.pythonhosted.org/packages/d0/11/00341177ae71c6f5159a08168bcb98c6e6d196d372c94511f9f6c9afe0c6/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", size = 141285 }, + { url = "https://files.pythonhosted.org/packages/01/09/11d684ea5819e5a8f5100fb0b38cf8d02b514746607934134d31233e02c8/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", size = 151449 }, + { url = "https://files.pythonhosted.org/packages/08/06/9f5a12939db324d905dc1f70591ae7d7898d030d7662f0d426e2286f68c9/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", size = 143892 }, + { url = "https://files.pythonhosted.org/packages/93/62/5e89cdfe04584cb7f4d36003ffa2936681b03ecc0754f8e969c2becb7e24/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", size = 146123 }, + { url = "https://files.pythonhosted.org/packages/a9/ac/ab729a15c516da2ab70a05f8722ecfccc3f04ed7a18e45c75bbbaa347d61/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", size = 147943 }, + { url = "https://files.pythonhosted.org/packages/03/d2/3f392f23f042615689456e9a274640c1d2e5dd1d52de36ab8f7955f8f050/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", size = 142063 }, + { url = "https://files.pythonhosted.org/packages/f2/e3/e20aae5e1039a2cd9b08d9205f52142329f887f8cf70da3650326670bddf/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", size = 150578 }, + { url = "https://files.pythonhosted.org/packages/8d/af/779ad72a4da0aed925e1139d458adc486e61076d7ecdcc09e610ea8678db/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", size = 153629 }, + { url = "https://files.pythonhosted.org/packages/c2/b6/7aa450b278e7aa92cf7732140bfd8be21f5f29d5bf334ae987c945276639/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", size = 150778 }, + { url = "https://files.pythonhosted.org/packages/39/f4/d9f4f712d0951dcbfd42920d3db81b00dd23b6ab520419626f4023334056/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", size = 146453 }, + { url = "https://files.pythonhosted.org/packages/49/2b/999d0314e4ee0cff3cb83e6bc9aeddd397eeed693edb4facb901eb8fbb69/charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", size = 95479 }, + { url = "https://files.pythonhosted.org/packages/2d/ce/3cbed41cff67e455a386fb5e5dd8906cdda2ed92fbc6297921f2e4419309/charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", size = 102790 }, + { url = "https://files.pythonhosted.org/packages/72/80/41ef5d5a7935d2d3a773e3eaebf0a9350542f2cab4eac59a7a4741fbbbbe/charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", size = 194995 }, + { url = "https://files.pythonhosted.org/packages/7a/28/0b9fefa7b8b080ec492110af6d88aa3dea91c464b17d53474b6e9ba5d2c5/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", size = 139471 }, + { url = "https://files.pythonhosted.org/packages/71/64/d24ab1a997efb06402e3fc07317e94da358e2585165930d9d59ad45fcae2/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", size = 149831 }, + { url = "https://files.pythonhosted.org/packages/37/ed/be39e5258e198655240db5e19e0b11379163ad7070962d6b0c87ed2c4d39/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", size = 142335 }, + { url = "https://files.pythonhosted.org/packages/88/83/489e9504711fa05d8dde1574996408026bdbdbd938f23be67deebb5eca92/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", size = 143862 }, + { url = "https://files.pythonhosted.org/packages/c6/c7/32da20821cf387b759ad24627a9aca289d2822de929b8a41b6241767b461/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", size = 145673 }, + { url = "https://files.pythonhosted.org/packages/68/85/f4288e96039abdd5aeb5c546fa20a37b50da71b5cf01e75e87f16cd43304/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", size = 140211 }, + { url = "https://files.pythonhosted.org/packages/28/a3/a42e70d03cbdabc18997baf4f0227c73591a08041c149e710045c281f97b/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", size = 148039 }, + { url = "https://files.pythonhosted.org/packages/85/e4/65699e8ab3014ecbe6f5c71d1a55d810fb716bbfd74f6283d5c2aa87febf/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", size = 151939 }, + { url = "https://files.pythonhosted.org/packages/b1/82/8e9fe624cc5374193de6860aba3ea8070f584c8565ee77c168ec13274bd2/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", size = 149075 }, + { url = "https://files.pythonhosted.org/packages/3d/7b/82865ba54c765560c8433f65e8acb9217cb839a9e32b42af4aa8e945870f/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", size = 144340 }, + { url = "https://files.pythonhosted.org/packages/b5/b6/9674a4b7d4d99a0d2df9b215da766ee682718f88055751e1e5e753c82db0/charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", size = 95205 }, + { url = "https://files.pythonhosted.org/packages/1e/ab/45b180e175de4402dcf7547e4fb617283bae54ce35c27930a6f35b6bef15/charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", size = 102441 }, + { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105 }, + { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404 }, + { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423 }, + { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184 }, + { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268 }, + { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601 }, + { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098 }, + { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520 }, + { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852 }, + { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488 }, + { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192 }, + { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550 }, + { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785 }, + { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 }, + { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 }, + { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 }, + { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 }, + { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 }, + { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 }, + { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 }, + { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 }, + { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 }, + { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 }, + { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 }, + { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 }, + { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 }, + { url = "https://files.pythonhosted.org/packages/10/bd/6517ea94f2672e801011d50b5d06be2a0deaf566aea27bcdcd47e5195357/charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c", size = 195653 }, + { url = "https://files.pythonhosted.org/packages/e5/0d/815a2ba3f283b4eeaa5ece57acade365c5b4135f65a807a083c818716582/charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9", size = 140701 }, + { url = "https://files.pythonhosted.org/packages/aa/17/c94be7ee0d142687e047fe1de72060f6d6837f40eedc26e87e6e124a3fc6/charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8", size = 150495 }, + { url = "https://files.pythonhosted.org/packages/f7/33/557ac796c47165fc141e4fb71d7b0310f67e05cb420756f3a82e0a0068e0/charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6", size = 142946 }, + { url = "https://files.pythonhosted.org/packages/1e/0d/38ef4ae41e9248d63fc4998d933cae22473b1b2ac4122cf908d0f5eb32aa/charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c", size = 144737 }, + { url = "https://files.pythonhosted.org/packages/43/01/754cdb29dd0560f58290aaaa284d43eea343ad0512e6ad3b8b5c11f08592/charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a", size = 147471 }, + { url = "https://files.pythonhosted.org/packages/ba/cd/861883ba5160c7a9bd242c30b2c71074cda2aefcc0addc91118e0d4e0765/charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd", size = 140801 }, + { url = "https://files.pythonhosted.org/packages/6f/7f/0c0dad447819e90b93f8ed238cc8f11b91353c23c19e70fa80483a155bed/charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd", size = 149312 }, + { url = "https://files.pythonhosted.org/packages/8e/09/9f8abcc6fff60fb727268b63c376c8c79cc37b833c2dfe1f535dfb59523b/charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824", size = 152347 }, + { url = "https://files.pythonhosted.org/packages/be/e5/3f363dad2e24378f88ccf63ecc39e817c29f32e308ef21a7a6d9c1201165/charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca", size = 149888 }, + { url = "https://files.pythonhosted.org/packages/e4/10/a78c0e91f487b4ad0ef7480ac765e15b774f83de2597f1b6ef0eaf7a2f99/charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b", size = 145169 }, + { url = "https://files.pythonhosted.org/packages/d3/81/396e7d7f5d7420da8273c91175d2e9a3f569288e3611d521685e4b9ac9cc/charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e", size = 95094 }, + { url = "https://files.pythonhosted.org/packages/40/bb/20affbbd9ea29c71ea123769dc568a6d42052ff5089c5fe23e21e21084a6/charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4", size = 102139 }, + { url = "https://files.pythonhosted.org/packages/7f/c0/b913f8f02836ed9ab32ea643c6fe4d3325c3d8627cf6e78098671cafff86/charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", size = 197867 }, + { url = "https://files.pythonhosted.org/packages/0f/6c/2bee440303d705b6fb1e2ec789543edec83d32d258299b16eed28aad48e0/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", size = 141385 }, + { url = "https://files.pythonhosted.org/packages/3d/04/cb42585f07f6f9fd3219ffb6f37d5a39b4fd2db2355b23683060029c35f7/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", size = 151367 }, + { url = "https://files.pythonhosted.org/packages/54/54/2412a5b093acb17f0222de007cc129ec0e0df198b5ad2ce5699355269dfe/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", size = 143928 }, + { url = "https://files.pythonhosted.org/packages/5a/6d/e2773862b043dcf8a221342954f375392bb2ce6487bcd9f2c1b34e1d6781/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", size = 146203 }, + { url = "https://files.pythonhosted.org/packages/b9/f8/ca440ef60d8f8916022859885f231abb07ada3c347c03d63f283bec32ef5/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", size = 148082 }, + { url = "https://files.pythonhosted.org/packages/04/d2/42fd330901aaa4b805a1097856c2edf5095e260a597f65def493f4b8c833/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", size = 142053 }, + { url = "https://files.pythonhosted.org/packages/9e/af/3a97a4fa3c53586f1910dadfc916e9c4f35eeada36de4108f5096cb7215f/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", size = 150625 }, + { url = "https://files.pythonhosted.org/packages/26/ae/23d6041322a3556e4da139663d02fb1b3c59a23ab2e2b56432bd2ad63ded/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", size = 153549 }, + { url = "https://files.pythonhosted.org/packages/94/22/b8f2081c6a77cb20d97e57e0b385b481887aa08019d2459dc2858ed64871/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", size = 150945 }, + { url = "https://files.pythonhosted.org/packages/c7/0b/c5ec5092747f801b8b093cdf5610e732b809d6cb11f4c51e35fc28d1d389/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", size = 146595 }, + { url = "https://files.pythonhosted.org/packages/0c/5a/0b59704c38470df6768aa154cc87b1ac7c9bb687990a1559dc8765e8627e/charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", size = 95453 }, + { url = "https://files.pythonhosted.org/packages/85/2d/a9790237cb4d01a6d57afadc8573c8b73c609ade20b80f4cda30802009ee/charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", size = 102811 }, + { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 }, +] + +[[package]] +name = "click" +version = "8.1.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 }, +] + +[[package]] +name = "codecov" +version = "2.1.13" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", version = "7.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, + { name = "coverage", version = "7.6.12", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2c/bb/594b26d2c85616be6195a64289c578662678afa4910cef2d3ce8417cf73e/codecov-2.1.13.tar.gz", hash = "sha256:2362b685633caeaf45b9951a9b76ce359cd3581dd515b430c6c3f5dfb4d92a8c", size = 21416 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/02/18785edcdf6266cdd6c6dc7635f1cbeefd9a5b4c3bb8aff8bd681e9dd095/codecov-2.1.13-py2.py3-none-any.whl", hash = "sha256:c2ca5e51bba9ebb43644c43d0690148a55086f7f5e6fd36170858fa4206744d5", size = 16512 }, +] + +[[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 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "coverage" +version = "7.6.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.9'", +] +sdist = { url = "https://files.pythonhosted.org/packages/f7/08/7e37f82e4d1aead42a7443ff06a1e406aabf7302c4f00a546e4b320b994c/coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d", size = 798791 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/61/eb7ce5ed62bacf21beca4937a90fe32545c91a3c8a42a30c6616d48fc70d/coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16", size = 206690 }, + { url = "https://files.pythonhosted.org/packages/7d/73/041928e434442bd3afde5584bdc3f932fb4562b1597629f537387cec6f3d/coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36", size = 207127 }, + { url = "https://files.pythonhosted.org/packages/c7/c8/6ca52b5147828e45ad0242388477fdb90df2c6cbb9a441701a12b3c71bc8/coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02", size = 235654 }, + { url = "https://files.pythonhosted.org/packages/d5/da/9ac2b62557f4340270942011d6efeab9833648380109e897d48ab7c1035d/coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc", size = 233598 }, + { url = "https://files.pythonhosted.org/packages/53/23/9e2c114d0178abc42b6d8d5281f651a8e6519abfa0ef460a00a91f80879d/coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23", size = 234732 }, + { url = "https://files.pythonhosted.org/packages/0f/7e/a0230756fb133343a52716e8b855045f13342b70e48e8ad41d8a0d60ab98/coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34", size = 233816 }, + { url = "https://files.pythonhosted.org/packages/28/7c/3753c8b40d232b1e5eeaed798c875537cf3cb183fb5041017c1fdb7ec14e/coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c", size = 232325 }, + { url = "https://files.pythonhosted.org/packages/57/e3/818a2b2af5b7573b4b82cf3e9f137ab158c90ea750a8f053716a32f20f06/coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959", size = 233418 }, + { url = "https://files.pythonhosted.org/packages/c8/fb/4532b0b0cefb3f06d201648715e03b0feb822907edab3935112b61b885e2/coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232", size = 209343 }, + { url = "https://files.pythonhosted.org/packages/5a/25/af337cc7421eca1c187cc9c315f0a755d48e755d2853715bfe8c418a45fa/coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0", size = 210136 }, + { url = "https://files.pythonhosted.org/packages/ad/5f/67af7d60d7e8ce61a4e2ddcd1bd5fb787180c8d0ae0fbd073f903b3dd95d/coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93", size = 206796 }, + { url = "https://files.pythonhosted.org/packages/e1/0e/e52332389e057daa2e03be1fbfef25bb4d626b37d12ed42ae6281d0a274c/coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3", size = 207244 }, + { url = "https://files.pythonhosted.org/packages/aa/cd/766b45fb6e090f20f8927d9c7cb34237d41c73a939358bc881883fd3a40d/coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff", size = 239279 }, + { url = "https://files.pythonhosted.org/packages/70/6c/a9ccd6fe50ddaf13442a1e2dd519ca805cbe0f1fcd377fba6d8339b98ccb/coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d", size = 236859 }, + { url = "https://files.pythonhosted.org/packages/14/6f/8351b465febb4dbc1ca9929505202db909c5a635c6fdf33e089bbc3d7d85/coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6", size = 238549 }, + { url = "https://files.pythonhosted.org/packages/68/3c/289b81fa18ad72138e6d78c4c11a82b5378a312c0e467e2f6b495c260907/coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56", size = 237477 }, + { url = "https://files.pythonhosted.org/packages/ed/1c/aa1efa6459d822bd72c4abc0b9418cf268de3f60eeccd65dc4988553bd8d/coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234", size = 236134 }, + { url = "https://files.pythonhosted.org/packages/fb/c8/521c698f2d2796565fe9c789c2ee1ccdae610b3aa20b9b2ef980cc253640/coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133", size = 236910 }, + { url = "https://files.pythonhosted.org/packages/7d/30/033e663399ff17dca90d793ee8a2ea2890e7fdf085da58d82468b4220bf7/coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c", size = 209348 }, + { url = "https://files.pythonhosted.org/packages/20/05/0d1ccbb52727ccdadaa3ff37e4d2dc1cd4d47f0c3df9eb58d9ec8508ca88/coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6", size = 210230 }, + { url = "https://files.pythonhosted.org/packages/7e/d4/300fc921dff243cd518c7db3a4c614b7e4b2431b0d1145c1e274fd99bd70/coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778", size = 206983 }, + { url = "https://files.pythonhosted.org/packages/e1/ab/6bf00de5327ecb8db205f9ae596885417a31535eeda6e7b99463108782e1/coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391", size = 207221 }, + { url = "https://files.pythonhosted.org/packages/92/8f/2ead05e735022d1a7f3a0a683ac7f737de14850395a826192f0288703472/coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8", size = 240342 }, + { url = "https://files.pythonhosted.org/packages/0f/ef/94043e478201ffa85b8ae2d2c79b4081e5a1b73438aafafccf3e9bafb6b5/coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d", size = 237371 }, + { url = "https://files.pythonhosted.org/packages/1f/0f/c890339dd605f3ebc269543247bdd43b703cce6825b5ed42ff5f2d6122c7/coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca", size = 239455 }, + { url = "https://files.pythonhosted.org/packages/d1/04/7fd7b39ec7372a04efb0f70c70e35857a99b6a9188b5205efb4c77d6a57a/coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163", size = 238924 }, + { url = "https://files.pythonhosted.org/packages/ed/bf/73ce346a9d32a09cf369f14d2a06651329c984e106f5992c89579d25b27e/coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a", size = 237252 }, + { url = "https://files.pythonhosted.org/packages/86/74/1dc7a20969725e917b1e07fe71a955eb34bc606b938316bcc799f228374b/coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d", size = 238897 }, + { url = "https://files.pythonhosted.org/packages/b6/e9/d9cc3deceb361c491b81005c668578b0dfa51eed02cd081620e9a62f24ec/coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5", size = 209606 }, + { url = "https://files.pythonhosted.org/packages/47/c8/5a2e41922ea6740f77d555c4d47544acd7dc3f251fe14199c09c0f5958d3/coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb", size = 210373 }, + { url = "https://files.pythonhosted.org/packages/8c/f9/9aa4dfb751cb01c949c990d136a0f92027fbcc5781c6e921df1cb1563f20/coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106", size = 207007 }, + { url = "https://files.pythonhosted.org/packages/b9/67/e1413d5a8591622a46dd04ff80873b04c849268831ed5c304c16433e7e30/coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9", size = 207269 }, + { url = "https://files.pythonhosted.org/packages/14/5b/9dec847b305e44a5634d0fb8498d135ab1d88330482b74065fcec0622224/coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c", size = 239886 }, + { url = "https://files.pythonhosted.org/packages/7b/b7/35760a67c168e29f454928f51f970342d23cf75a2bb0323e0f07334c85f3/coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a", size = 237037 }, + { url = "https://files.pythonhosted.org/packages/f7/95/d2fd31f1d638df806cae59d7daea5abf2b15b5234016a5ebb502c2f3f7ee/coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060", size = 239038 }, + { url = "https://files.pythonhosted.org/packages/6e/bd/110689ff5752b67924efd5e2aedf5190cbbe245fc81b8dec1abaffba619d/coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862", size = 238690 }, + { url = "https://files.pythonhosted.org/packages/d3/a8/08d7b38e6ff8df52331c83130d0ab92d9c9a8b5462f9e99c9f051a4ae206/coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388", size = 236765 }, + { url = "https://files.pythonhosted.org/packages/d6/6a/9cf96839d3147d55ae713eb2d877f4d777e7dc5ba2bce227167d0118dfe8/coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155", size = 238611 }, + { url = "https://files.pythonhosted.org/packages/74/e4/7ff20d6a0b59eeaab40b3140a71e38cf52547ba21dbcf1d79c5a32bba61b/coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a", size = 209671 }, + { url = "https://files.pythonhosted.org/packages/35/59/1812f08a85b57c9fdb6d0b383d779e47b6f643bc278ed682859512517e83/coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129", size = 210368 }, + { url = "https://files.pythonhosted.org/packages/9c/15/08913be1c59d7562a3e39fce20661a98c0a3f59d5754312899acc6cb8a2d/coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e", size = 207758 }, + { url = "https://files.pythonhosted.org/packages/c4/ae/b5d58dff26cade02ada6ca612a76447acd69dccdbb3a478e9e088eb3d4b9/coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962", size = 208035 }, + { url = "https://files.pythonhosted.org/packages/b8/d7/62095e355ec0613b08dfb19206ce3033a0eedb6f4a67af5ed267a8800642/coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb", size = 250839 }, + { url = "https://files.pythonhosted.org/packages/7c/1e/c2967cb7991b112ba3766df0d9c21de46b476d103e32bb401b1b2adf3380/coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704", size = 246569 }, + { url = "https://files.pythonhosted.org/packages/8b/61/a7a6a55dd266007ed3b1df7a3386a0d760d014542d72f7c2c6938483b7bd/coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b", size = 248927 }, + { url = "https://files.pythonhosted.org/packages/c8/fa/13a6f56d72b429f56ef612eb3bc5ce1b75b7ee12864b3bd12526ab794847/coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f", size = 248401 }, + { url = "https://files.pythonhosted.org/packages/75/06/0429c652aa0fb761fc60e8c6b291338c9173c6aa0f4e40e1902345b42830/coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223", size = 246301 }, + { url = "https://files.pythonhosted.org/packages/52/76/1766bb8b803a88f93c3a2d07e30ffa359467810e5cbc68e375ebe6906efb/coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3", size = 247598 }, + { url = "https://files.pythonhosted.org/packages/66/8b/f54f8db2ae17188be9566e8166ac6df105c1c611e25da755738025708d54/coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f", size = 210307 }, + { url = "https://files.pythonhosted.org/packages/9f/b0/e0dca6da9170aefc07515cce067b97178cefafb512d00a87a1c717d2efd5/coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657", size = 211453 }, + { url = "https://files.pythonhosted.org/packages/81/d0/d9e3d554e38beea5a2e22178ddb16587dbcbe9a1ef3211f55733924bf7fa/coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0", size = 206674 }, + { url = "https://files.pythonhosted.org/packages/38/ea/cab2dc248d9f45b2b7f9f1f596a4d75a435cb364437c61b51d2eb33ceb0e/coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a", size = 207101 }, + { url = "https://files.pythonhosted.org/packages/ca/6f/f82f9a500c7c5722368978a5390c418d2a4d083ef955309a8748ecaa8920/coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b", size = 236554 }, + { url = "https://files.pythonhosted.org/packages/a6/94/d3055aa33d4e7e733d8fa309d9adf147b4b06a82c1346366fc15a2b1d5fa/coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3", size = 234440 }, + { url = "https://files.pythonhosted.org/packages/e4/6e/885bcd787d9dd674de4a7d8ec83faf729534c63d05d51d45d4fa168f7102/coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de", size = 235889 }, + { url = "https://files.pythonhosted.org/packages/f4/63/df50120a7744492710854860783d6819ff23e482dee15462c9a833cc428a/coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6", size = 235142 }, + { url = "https://files.pythonhosted.org/packages/3a/5d/9d0acfcded2b3e9ce1c7923ca52ccc00c78a74e112fc2aee661125b7843b/coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569", size = 233805 }, + { url = "https://files.pythonhosted.org/packages/c4/56/50abf070cb3cd9b1dd32f2c88f083aab561ecbffbcd783275cb51c17f11d/coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989", size = 234655 }, + { url = "https://files.pythonhosted.org/packages/25/ee/b4c246048b8485f85a2426ef4abab88e48c6e80c74e964bea5cd4cd4b115/coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7", size = 209296 }, + { url = "https://files.pythonhosted.org/packages/5c/1c/96cf86b70b69ea2b12924cdf7cabb8ad10e6130eab8d767a1099fbd2a44f/coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8", size = 210137 }, + { url = "https://files.pythonhosted.org/packages/19/d3/d54c5aa83268779d54c86deb39c1c4566e5d45c155369ca152765f8db413/coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255", size = 206688 }, + { url = "https://files.pythonhosted.org/packages/a5/fe/137d5dca72e4a258b1bc17bb04f2e0196898fe495843402ce826a7419fe3/coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8", size = 207120 }, + { url = "https://files.pythonhosted.org/packages/78/5b/a0a796983f3201ff5485323b225d7c8b74ce30c11f456017e23d8e8d1945/coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2", size = 235249 }, + { url = "https://files.pythonhosted.org/packages/4e/e1/76089d6a5ef9d68f018f65411fcdaaeb0141b504587b901d74e8587606ad/coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a", size = 233237 }, + { url = "https://files.pythonhosted.org/packages/9a/6f/eef79b779a540326fee9520e5542a8b428cc3bfa8b7c8f1022c1ee4fc66c/coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc", size = 234311 }, + { url = "https://files.pythonhosted.org/packages/75/e1/656d65fb126c29a494ef964005702b012f3498db1a30dd562958e85a4049/coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004", size = 233453 }, + { url = "https://files.pythonhosted.org/packages/68/6a/45f108f137941a4a1238c85f28fd9d048cc46b5466d6b8dda3aba1bb9d4f/coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb", size = 231958 }, + { url = "https://files.pythonhosted.org/packages/9b/e7/47b809099168b8b8c72ae311efc3e88c8d8a1162b3ba4b8da3cfcdb85743/coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36", size = 232938 }, + { url = "https://files.pythonhosted.org/packages/52/80/052222ba7058071f905435bad0ba392cc12006380731c37afaf3fe749b88/coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c", size = 209352 }, + { url = "https://files.pythonhosted.org/packages/b8/d8/1b92e0b3adcf384e98770a00ca095da1b5f7b483e6563ae4eb5e935d24a1/coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca", size = 210153 }, + { url = "https://files.pythonhosted.org/packages/a5/2b/0354ed096bca64dc8e32a7cbcae28b34cb5ad0b1fe2125d6d99583313ac0/coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df", size = 198926 }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version < '3.9'" }, +] + +[[package]] +name = "coverage" +version = "7.6.12" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.9'", +] +sdist = { url = "https://files.pythonhosted.org/packages/0c/d6/2b53ab3ee99f2262e6f0b8369a43f6d66658eab45510331c0b3d5c8c4272/coverage-7.6.12.tar.gz", hash = "sha256:48cfc4641d95d34766ad41d9573cc0f22a48aa88d22657a1fe01dca0dbae4de2", size = 805941 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/67/81dc41ec8f548c365d04a29f1afd492d3176b372c33e47fa2a45a01dc13a/coverage-7.6.12-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:704c8c8c6ce6569286ae9622e534b4f5b9759b6f2cd643f1c1a61f666d534fe8", size = 208345 }, + { url = "https://files.pythonhosted.org/packages/33/43/17f71676016c8829bde69e24c852fef6bd9ed39f774a245d9ec98f689fa0/coverage-7.6.12-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ad7525bf0241e5502168ae9c643a2f6c219fa0a283001cee4cf23a9b7da75879", size = 208775 }, + { url = "https://files.pythonhosted.org/packages/86/25/c6ff0775f8960e8c0840845b723eed978d22a3cd9babd2b996e4a7c502c6/coverage-7.6.12-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06097c7abfa611c91edb9e6920264e5be1d6ceb374efb4986f38b09eed4cb2fe", size = 237925 }, + { url = "https://files.pythonhosted.org/packages/b0/3d/5f5bd37046243cb9d15fff2c69e498c2f4fe4f9b42a96018d4579ed3506f/coverage-7.6.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:220fa6c0ad7d9caef57f2c8771918324563ef0d8272c94974717c3909664e674", size = 235835 }, + { url = "https://files.pythonhosted.org/packages/b5/f1/9e6b75531fe33490b910d251b0bf709142e73a40e4e38a3899e6986fe088/coverage-7.6.12-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3688b99604a24492bcfe1c106278c45586eb819bf66a654d8a9a1433022fb2eb", size = 236966 }, + { url = "https://files.pythonhosted.org/packages/4f/bc/aef5a98f9133851bd1aacf130e754063719345d2fb776a117d5a8d516971/coverage-7.6.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d1a987778b9c71da2fc8948e6f2656da6ef68f59298b7e9786849634c35d2c3c", size = 236080 }, + { url = "https://files.pythonhosted.org/packages/eb/d0/56b4ab77f9b12aea4d4c11dc11cdcaa7c29130b837eb610639cf3400c9c3/coverage-7.6.12-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:cec6b9ce3bd2b7853d4a4563801292bfee40b030c05a3d29555fd2a8ee9bd68c", size = 234393 }, + { url = "https://files.pythonhosted.org/packages/0d/77/28ef95c5d23fe3dd191a0b7d89c82fea2c2d904aef9315daf7c890e96557/coverage-7.6.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ace9048de91293e467b44bce0f0381345078389814ff6e18dbac8fdbf896360e", size = 235536 }, + { url = "https://files.pythonhosted.org/packages/29/62/18791d3632ee3ff3f95bc8599115707d05229c72db9539f208bb878a3d88/coverage-7.6.12-cp310-cp310-win32.whl", hash = "sha256:ea31689f05043d520113e0552f039603c4dd71fa4c287b64cb3606140c66f425", size = 211063 }, + { url = "https://files.pythonhosted.org/packages/fc/57/b3878006cedfd573c963e5c751b8587154eb10a61cc0f47a84f85c88a355/coverage-7.6.12-cp310-cp310-win_amd64.whl", hash = "sha256:676f92141e3c5492d2a1596d52287d0d963df21bf5e55c8b03075a60e1ddf8aa", size = 211955 }, + { url = "https://files.pythonhosted.org/packages/64/2d/da78abbfff98468c91fd63a73cccdfa0e99051676ded8dd36123e3a2d4d5/coverage-7.6.12-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e18aafdfb3e9ec0d261c942d35bd7c28d031c5855dadb491d2723ba54f4c3015", size = 208464 }, + { url = "https://files.pythonhosted.org/packages/31/f2/c269f46c470bdabe83a69e860c80a82e5e76840e9f4bbd7f38f8cebbee2f/coverage-7.6.12-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:66fe626fd7aa5982cdebad23e49e78ef7dbb3e3c2a5960a2b53632f1f703ea45", size = 208893 }, + { url = "https://files.pythonhosted.org/packages/47/63/5682bf14d2ce20819998a49c0deadb81e608a59eed64d6bc2191bc8046b9/coverage-7.6.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ef01d70198431719af0b1f5dcbefc557d44a190e749004042927b2a3fed0702", size = 241545 }, + { url = "https://files.pythonhosted.org/packages/6a/b6/6b6631f1172d437e11067e1c2edfdb7238b65dff965a12bce3b6d1bf2be2/coverage-7.6.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e92ae5a289a4bc4c0aae710c0948d3c7892e20fd3588224ebe242039573bf0", size = 239230 }, + { url = "https://files.pythonhosted.org/packages/c7/01/9cd06cbb1be53e837e16f1b4309f6357e2dfcbdab0dd7cd3b1a50589e4e1/coverage-7.6.12-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e695df2c58ce526eeab11a2e915448d3eb76f75dffe338ea613c1201b33bab2f", size = 241013 }, + { url = "https://files.pythonhosted.org/packages/4b/26/56afefc03c30871326e3d99709a70d327ac1f33da383cba108c79bd71563/coverage-7.6.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d74c08e9aaef995f8c4ef6d202dbd219c318450fe2a76da624f2ebb9c8ec5d9f", size = 239750 }, + { url = "https://files.pythonhosted.org/packages/dd/ea/88a1ff951ed288f56aa561558ebe380107cf9132facd0b50bced63ba7238/coverage-7.6.12-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e995b3b76ccedc27fe4f477b349b7d64597e53a43fc2961db9d3fbace085d69d", size = 238462 }, + { url = "https://files.pythonhosted.org/packages/6e/d4/1d9404566f553728889409eff82151d515fbb46dc92cbd13b5337fa0de8c/coverage-7.6.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b1f097878d74fe51e1ddd1be62d8e3682748875b461232cf4b52ddc6e6db0bba", size = 239307 }, + { url = "https://files.pythonhosted.org/packages/12/c1/e453d3b794cde1e232ee8ac1d194fde8e2ba329c18bbf1b93f6f5eef606b/coverage-7.6.12-cp311-cp311-win32.whl", hash = "sha256:1f7ffa05da41754e20512202c866d0ebfc440bba3b0ed15133070e20bf5aeb5f", size = 211117 }, + { url = "https://files.pythonhosted.org/packages/d5/db/829185120c1686fa297294f8fcd23e0422f71070bf85ef1cc1a72ecb2930/coverage-7.6.12-cp311-cp311-win_amd64.whl", hash = "sha256:e216c5c45f89ef8971373fd1c5d8d1164b81f7f5f06bbf23c37e7908d19e8558", size = 212019 }, + { url = "https://files.pythonhosted.org/packages/e2/7f/4af2ed1d06ce6bee7eafc03b2ef748b14132b0bdae04388e451e4b2c529b/coverage-7.6.12-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b172f8e030e8ef247b3104902cc671e20df80163b60a203653150d2fc204d1ad", size = 208645 }, + { url = "https://files.pythonhosted.org/packages/dc/60/d19df912989117caa95123524d26fc973f56dc14aecdec5ccd7d0084e131/coverage-7.6.12-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:641dfe0ab73deb7069fb972d4d9725bf11c239c309ce694dd50b1473c0f641c3", size = 208898 }, + { url = "https://files.pythonhosted.org/packages/bd/10/fecabcf438ba676f706bf90186ccf6ff9f6158cc494286965c76e58742fa/coverage-7.6.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e549f54ac5f301e8e04c569dfdb907f7be71b06b88b5063ce9d6953d2d58574", size = 242987 }, + { url = "https://files.pythonhosted.org/packages/4c/53/4e208440389e8ea936f5f2b0762dcd4cb03281a7722def8e2bf9dc9c3d68/coverage-7.6.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:959244a17184515f8c52dcb65fb662808767c0bd233c1d8a166e7cf74c9ea985", size = 239881 }, + { url = "https://files.pythonhosted.org/packages/c4/47/2ba744af8d2f0caa1f17e7746147e34dfc5f811fb65fc153153722d58835/coverage-7.6.12-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bda1c5f347550c359f841d6614fb8ca42ae5cb0b74d39f8a1e204815ebe25750", size = 242142 }, + { url = "https://files.pythonhosted.org/packages/e9/90/df726af8ee74d92ee7e3bf113bf101ea4315d71508952bd21abc3fae471e/coverage-7.6.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1ceeb90c3eda1f2d8c4c578c14167dbd8c674ecd7d38e45647543f19839dd6ea", size = 241437 }, + { url = "https://files.pythonhosted.org/packages/f6/af/995263fd04ae5f9cf12521150295bf03b6ba940d0aea97953bb4a6db3e2b/coverage-7.6.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f16f44025c06792e0fb09571ae454bcc7a3ec75eeb3c36b025eccf501b1a4c3", size = 239724 }, + { url = "https://files.pythonhosted.org/packages/1c/8e/5bb04f0318805e190984c6ce106b4c3968a9562a400180e549855d8211bd/coverage-7.6.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b076e625396e787448d27a411aefff867db2bffac8ed04e8f7056b07024eed5a", size = 241329 }, + { url = "https://files.pythonhosted.org/packages/9e/9d/fa04d9e6c3f6459f4e0b231925277cfc33d72dfab7fa19c312c03e59da99/coverage-7.6.12-cp312-cp312-win32.whl", hash = "sha256:00b2086892cf06c7c2d74983c9595dc511acca00665480b3ddff749ec4fb2a95", size = 211289 }, + { url = "https://files.pythonhosted.org/packages/53/40/53c7ffe3c0c3fff4d708bc99e65f3d78c129110d6629736faf2dbd60ad57/coverage-7.6.12-cp312-cp312-win_amd64.whl", hash = "sha256:7ae6eabf519bc7871ce117fb18bf14e0e343eeb96c377667e3e5dd12095e0288", size = 212079 }, + { url = "https://files.pythonhosted.org/packages/76/89/1adf3e634753c0de3dad2f02aac1e73dba58bc5a3a914ac94a25b2ef418f/coverage-7.6.12-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:488c27b3db0ebee97a830e6b5a3ea930c4a6e2c07f27a5e67e1b3532e76b9ef1", size = 208673 }, + { url = "https://files.pythonhosted.org/packages/ce/64/92a4e239d64d798535c5b45baac6b891c205a8a2e7c9cc8590ad386693dc/coverage-7.6.12-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d1095bbee1851269f79fd8e0c9b5544e4c00c0c24965e66d8cba2eb5bb535fd", size = 208945 }, + { url = "https://files.pythonhosted.org/packages/b4/d0/4596a3ef3bca20a94539c9b1e10fd250225d1dec57ea78b0867a1cf9742e/coverage-7.6.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0533adc29adf6a69c1baa88c3d7dbcaadcffa21afbed3ca7a225a440e4744bf9", size = 242484 }, + { url = "https://files.pythonhosted.org/packages/1c/ef/6fd0d344695af6718a38d0861408af48a709327335486a7ad7e85936dc6e/coverage-7.6.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53c56358d470fa507a2b6e67a68fd002364d23c83741dbc4c2e0680d80ca227e", size = 239525 }, + { url = "https://files.pythonhosted.org/packages/0c/4b/373be2be7dd42f2bcd6964059fd8fa307d265a29d2b9bcf1d044bcc156ed/coverage-7.6.12-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64cbb1a3027c79ca6310bf101014614f6e6e18c226474606cf725238cf5bc2d4", size = 241545 }, + { url = "https://files.pythonhosted.org/packages/a6/7d/0e83cc2673a7790650851ee92f72a343827ecaaea07960587c8f442b5cd3/coverage-7.6.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:79cac3390bfa9836bb795be377395f28410811c9066bc4eefd8015258a7578c6", size = 241179 }, + { url = "https://files.pythonhosted.org/packages/ff/8c/566ea92ce2bb7627b0900124e24a99f9244b6c8c92d09ff9f7633eb7c3c8/coverage-7.6.12-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9b148068e881faa26d878ff63e79650e208e95cf1c22bd3f77c3ca7b1d9821a3", size = 239288 }, + { url = "https://files.pythonhosted.org/packages/7d/e4/869a138e50b622f796782d642c15fb5f25a5870c6d0059a663667a201638/coverage-7.6.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8bec2ac5da793c2685ce5319ca9bcf4eee683b8a1679051f8e6ec04c4f2fd7dc", size = 241032 }, + { url = "https://files.pythonhosted.org/packages/ae/28/a52ff5d62a9f9e9fe9c4f17759b98632edd3a3489fce70154c7d66054dd3/coverage-7.6.12-cp313-cp313-win32.whl", hash = "sha256:200e10beb6ddd7c3ded322a4186313d5ca9e63e33d8fab4faa67ef46d3460af3", size = 211315 }, + { url = "https://files.pythonhosted.org/packages/bc/17/ab849b7429a639f9722fa5628364c28d675c7ff37ebc3268fe9840dda13c/coverage-7.6.12-cp313-cp313-win_amd64.whl", hash = "sha256:2b996819ced9f7dbb812c701485d58f261bef08f9b85304d41219b1496b591ef", size = 212099 }, + { url = "https://files.pythonhosted.org/packages/d2/1c/b9965bf23e171d98505eb5eb4fb4d05c44efd256f2e0f19ad1ba8c3f54b0/coverage-7.6.12-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:299cf973a7abff87a30609879c10df0b3bfc33d021e1adabc29138a48888841e", size = 209511 }, + { url = "https://files.pythonhosted.org/packages/57/b3/119c201d3b692d5e17784fee876a9a78e1b3051327de2709392962877ca8/coverage-7.6.12-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4b467a8c56974bf06e543e69ad803c6865249d7a5ccf6980457ed2bc50312703", size = 209729 }, + { url = "https://files.pythonhosted.org/packages/52/4e/a7feb5a56b266304bc59f872ea07b728e14d5a64f1ad3a2cc01a3259c965/coverage-7.6.12-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2458f275944db8129f95d91aee32c828a408481ecde3b30af31d552c2ce284a0", size = 253988 }, + { url = "https://files.pythonhosted.org/packages/65/19/069fec4d6908d0dae98126aa7ad08ce5130a6decc8509da7740d36e8e8d2/coverage-7.6.12-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a9d8be07fb0832636a0f72b80d2a652fe665e80e720301fb22b191c3434d924", size = 249697 }, + { url = "https://files.pythonhosted.org/packages/1c/da/5b19f09ba39df7c55f77820736bf17bbe2416bbf5216a3100ac019e15839/coverage-7.6.12-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14d47376a4f445e9743f6c83291e60adb1b127607a3618e3185bbc8091f0467b", size = 252033 }, + { url = "https://files.pythonhosted.org/packages/1e/89/4c2750df7f80a7872267f7c5fe497c69d45f688f7b3afe1297e52e33f791/coverage-7.6.12-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b95574d06aa9d2bd6e5cc35a5bbe35696342c96760b69dc4287dbd5abd4ad51d", size = 251535 }, + { url = "https://files.pythonhosted.org/packages/78/3b/6d3ae3c1cc05f1b0460c51e6f6dcf567598cbd7c6121e5ad06643974703c/coverage-7.6.12-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:ecea0c38c9079570163d663c0433a9af4094a60aafdca491c6a3d248c7432827", size = 249192 }, + { url = "https://files.pythonhosted.org/packages/6e/8e/c14a79f535ce41af7d436bbad0d3d90c43d9e38ec409b4770c894031422e/coverage-7.6.12-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2251fabcfee0a55a8578a9d29cecfee5f2de02f11530e7d5c5a05859aa85aee9", size = 250627 }, + { url = "https://files.pythonhosted.org/packages/cb/79/b7cee656cfb17a7f2c1b9c3cee03dd5d8000ca299ad4038ba64b61a9b044/coverage-7.6.12-cp313-cp313t-win32.whl", hash = "sha256:eb5507795caabd9b2ae3f1adc95f67b1104971c22c624bb354232d65c4fc90b3", size = 212033 }, + { url = "https://files.pythonhosted.org/packages/b6/c3/f7aaa3813f1fa9a4228175a7bd368199659d392897e184435a3b66408dd3/coverage-7.6.12-cp313-cp313t-win_amd64.whl", hash = "sha256:f60a297c3987c6c02ffb29effc70eadcbb412fe76947d394a1091a3615948e2f", size = 213240 }, + { url = "https://files.pythonhosted.org/packages/6c/eb/cf062b1c3dbdcafd64a2a154beea2e4aa8e9886c34e41f53fa04925c8b35/coverage-7.6.12-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e7575ab65ca8399c8c4f9a7d61bbd2d204c8b8e447aab9d355682205c9dd948d", size = 208343 }, + { url = "https://files.pythonhosted.org/packages/95/42/4ebad0ab065228e29869a060644712ab1b0821d8c29bfefa20c2118c9e19/coverage-7.6.12-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8161d9fbc7e9fe2326de89cd0abb9f3599bccc1287db0aba285cb68d204ce929", size = 208769 }, + { url = "https://files.pythonhosted.org/packages/44/9f/421e84f7f9455eca85ff85546f26cbc144034bb2587e08bfc214dd6e9c8f/coverage-7.6.12-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a1e465f398c713f1b212400b4e79a09829cd42aebd360362cd89c5bdc44eb87", size = 237553 }, + { url = "https://files.pythonhosted.org/packages/c9/c4/a2c4f274bcb711ed5db2ccc1b851ca1c45f35ed6077aec9d6c61845d80e3/coverage-7.6.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f25d8b92a4e31ff1bd873654ec367ae811b3a943583e05432ea29264782dc32c", size = 235473 }, + { url = "https://files.pythonhosted.org/packages/e0/10/a3d317e38e5627b06debe861d6c511b1611dd9dc0e2a47afbe6257ffd341/coverage-7.6.12-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a936309a65cc5ca80fa9f20a442ff9e2d06927ec9a4f54bcba9c14c066323f2", size = 236575 }, + { url = "https://files.pythonhosted.org/packages/4d/49/51cd991b56257d2e07e3d5cb053411e9de5b0f4e98047167ec05e4e19b55/coverage-7.6.12-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:aa6f302a3a0b5f240ee201297fff0bbfe2fa0d415a94aeb257d8b461032389bd", size = 235690 }, + { url = "https://files.pythonhosted.org/packages/f7/87/631e5883fe0a80683a1f20dadbd0f99b79e17a9d8ea9aff3a9b4cfe50b93/coverage-7.6.12-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f973643ef532d4f9be71dd88cf7588936685fdb576d93a79fe9f65bc337d9d73", size = 234040 }, + { url = "https://files.pythonhosted.org/packages/7c/34/edd03f6933f766ec97dddd178a7295855f8207bb708dbac03777107ace5b/coverage-7.6.12-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:78f5243bb6b1060aed6213d5107744c19f9571ec76d54c99cc15938eb69e0e86", size = 235048 }, + { url = "https://files.pythonhosted.org/packages/ee/1e/d45045b7d3012fe518c617a57b9f9396cdaebe6455f1b404858b32c38cdd/coverage-7.6.12-cp39-cp39-win32.whl", hash = "sha256:69e62c5034291c845fc4df7f8155e8544178b6c774f97a99e2734b05eb5bed31", size = 211085 }, + { url = "https://files.pythonhosted.org/packages/df/ea/086cb06af14a84fe773b86aa140892006a906c5ec947e609ceb6a93f6257/coverage-7.6.12-cp39-cp39-win_amd64.whl", hash = "sha256:b01a840ecc25dce235ae4c1b6a0daefb2a203dba0e6e980637ee9c2f6ee0df57", size = 211965 }, + { url = "https://files.pythonhosted.org/packages/7a/7f/05818c62c7afe75df11e0233bd670948d68b36cdbf2a339a095bc02624a8/coverage-7.6.12-pp39.pp310-none-any.whl", hash = "sha256:7e39e845c4d764208e7b8f6a21c541ade741e2c41afabdfa1caa28687a3c98cf", size = 200558 }, + { url = "https://files.pythonhosted.org/packages/fb/b2/f655700e1024dec98b10ebaafd0cedbc25e40e4abe62a3c8e2ceef4f8f0a/coverage-7.6.12-py3-none-any.whl", hash = "sha256:eb8668cfbc279a536c633137deeb9435d2962caec279c3f8cf8b91fff6ff8953", size = 200552 }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version >= '3.9' and python_full_version <= '3.11'" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, +] + +[[package]] +name = "ghp-import" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d9/29/d40217cbe2f6b1359e00c6c307bb3fc876ba74068cbab3dde77f03ca0dc4/ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343", size = 10943 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034 }, +] + +[[package]] +name = "gitdb" +version = "4.0.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "smmap" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794 }, +] + +[[package]] +name = "gitpython" +version = "3.1.44" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "gitdb" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/89/37df0b71473153574a5cdef8f242de422a0f5d26d7a9e231e6f169b4ad14/gitpython-3.1.44.tar.gz", hash = "sha256:c87e30b26253bf5418b01b0660f818967f3c503193838337fe5e573331249269", size = 214196 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/9a/4114a9057db2f1462d5c8f8390ab7383925fe1ac012eaa42402ad65c2963/GitPython-3.1.44-py3-none-any.whl", hash = "sha256:9e0e10cda9bed1ee64bc9a6de50e7e38a9c9943241cd7f585f6df3ed28011110", size = 207599 }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, +] + +[[package]] +name = "importlib-metadata" +version = "8.5.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.9'", +] +dependencies = [ + { name = "zipp", version = "3.20.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cd/12/33e59336dca5be0c398a7482335911a33aa0e20776128f038019f1a95f1b/importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7", size = 55304 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/d9/a1e041c5e7caa9a05c925f4bdbdfb7f006d1f74996af53467bc394c97be7/importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b", size = 26514 }, +] + +[[package]] +name = "importlib-metadata" +version = "8.6.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.9'", +] +dependencies = [ + { name = "zipp", version = "3.21.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/08/c1395a292bb23fd03bdf572a1357c5a733d3eecbab877641ceacab23db6e/importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580", size = 55767 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/9d/0fb148dc4d6fa4a7dd1d8378168d9b4cd8d4560a6fbf6f0121c5fc34eb68/importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e", size = 26971 }, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe", version = "2.1.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, + { name = "markupsafe", version = "3.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 }, +] + +[[package]] +name = "markdown" +version = "3.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "importlib-metadata", version = "8.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, + { name = "importlib-metadata", version = "8.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.9.*'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/54/28/3af612670f82f4c056911fbbbb42760255801b3068c48de792d354ff4472/markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2", size = 357086 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/08/83871f3c50fc983b88547c196d11cf8c3340e37c32d2e9d6152abe2c61f7/Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803", size = 106349 }, +] + +[[package]] +name = "markupsafe" +version = "2.1.5" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.9'", +] +sdist = { url = "https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", size = 19384 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/54/ad5eb37bf9d51800010a74e4665425831a9db4e7c4e0fde4352e391e808e/MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", size = 18206 }, + { url = "https://files.pythonhosted.org/packages/6a/4a/a4d49415e600bacae038c67f9fecc1d5433b9d3c71a4de6f33537b89654c/MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", size = 14079 }, + { url = "https://files.pythonhosted.org/packages/0a/7b/85681ae3c33c385b10ac0f8dd025c30af83c78cec1c37a6aa3b55e67f5ec/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", size = 26620 }, + { url = "https://files.pythonhosted.org/packages/7c/52/2b1b570f6b8b803cef5ac28fdf78c0da318916c7d2fe9402a84d591b394c/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", size = 25818 }, + { url = "https://files.pythonhosted.org/packages/29/fe/a36ba8c7ca55621620b2d7c585313efd10729e63ef81e4e61f52330da781/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", size = 25493 }, + { url = "https://files.pythonhosted.org/packages/60/ae/9c60231cdfda003434e8bd27282b1f4e197ad5a710c14bee8bea8a9ca4f0/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", size = 30630 }, + { url = "https://files.pythonhosted.org/packages/65/dc/1510be4d179869f5dafe071aecb3f1f41b45d37c02329dfba01ff59e5ac5/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", size = 29745 }, + { url = "https://files.pythonhosted.org/packages/30/39/8d845dd7d0b0613d86e0ef89549bfb5f61ed781f59af45fc96496e897f3a/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", size = 30021 }, + { url = "https://files.pythonhosted.org/packages/c7/5c/356a6f62e4f3c5fbf2602b4771376af22a3b16efa74eb8716fb4e328e01e/MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", size = 16659 }, + { url = "https://files.pythonhosted.org/packages/69/48/acbf292615c65f0604a0c6fc402ce6d8c991276e16c80c46a8f758fbd30c/MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", size = 17213 }, + { url = "https://files.pythonhosted.org/packages/11/e7/291e55127bb2ae67c64d66cef01432b5933859dfb7d6949daa721b89d0b3/MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", size = 18219 }, + { url = "https://files.pythonhosted.org/packages/6b/cb/aed7a284c00dfa7c0682d14df85ad4955a350a21d2e3b06d8240497359bf/MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", size = 14098 }, + { url = "https://files.pythonhosted.org/packages/1c/cf/35fe557e53709e93feb65575c93927942087e9b97213eabc3fe9d5b25a55/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", size = 29014 }, + { url = "https://files.pythonhosted.org/packages/97/18/c30da5e7a0e7f4603abfc6780574131221d9148f323752c2755d48abad30/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", size = 28220 }, + { url = "https://files.pythonhosted.org/packages/0c/40/2e73e7d532d030b1e41180807a80d564eda53babaf04d65e15c1cf897e40/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", size = 27756 }, + { url = "https://files.pythonhosted.org/packages/18/46/5dca760547e8c59c5311b332f70605d24c99d1303dd9a6e1fc3ed0d73561/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", size = 33988 }, + { url = "https://files.pythonhosted.org/packages/6d/c5/27febe918ac36397919cd4a67d5579cbbfa8da027fa1238af6285bb368ea/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", size = 32718 }, + { url = "https://files.pythonhosted.org/packages/f8/81/56e567126a2c2bc2684d6391332e357589a96a76cb9f8e5052d85cb0ead8/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", size = 33317 }, + { url = "https://files.pythonhosted.org/packages/00/0b/23f4b2470accb53285c613a3ab9ec19dc944eaf53592cb6d9e2af8aa24cc/MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", size = 16670 }, + { url = "https://files.pythonhosted.org/packages/b7/a2/c78a06a9ec6d04b3445a949615c4c7ed86a0b2eb68e44e7541b9d57067cc/MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", size = 17224 }, + { url = "https://files.pythonhosted.org/packages/53/bd/583bf3e4c8d6a321938c13f49d44024dbe5ed63e0a7ba127e454a66da974/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", size = 18215 }, + { url = "https://files.pythonhosted.org/packages/48/d6/e7cd795fc710292c3af3a06d80868ce4b02bfbbf370b7cee11d282815a2a/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", size = 14069 }, + { url = "https://files.pythonhosted.org/packages/51/b5/5d8ec796e2a08fc814a2c7d2584b55f889a55cf17dd1a90f2beb70744e5c/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", size = 29452 }, + { url = "https://files.pythonhosted.org/packages/0a/0d/2454f072fae3b5a137c119abf15465d1771319dfe9e4acbb31722a0fff91/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", size = 28462 }, + { url = "https://files.pythonhosted.org/packages/2d/75/fd6cb2e68780f72d47e6671840ca517bda5ef663d30ada7616b0462ad1e3/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", size = 27869 }, + { url = "https://files.pythonhosted.org/packages/b0/81/147c477391c2750e8fc7705829f7351cf1cd3be64406edcf900dc633feb2/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", size = 33906 }, + { url = "https://files.pythonhosted.org/packages/8b/ff/9a52b71839d7a256b563e85d11050e307121000dcebc97df120176b3ad93/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", size = 32296 }, + { url = "https://files.pythonhosted.org/packages/88/07/2dc76aa51b481eb96a4c3198894f38b480490e834479611a4053fbf08623/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", size = 33038 }, + { url = "https://files.pythonhosted.org/packages/96/0c/620c1fb3661858c0e37eb3cbffd8c6f732a67cd97296f725789679801b31/MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", size = 16572 }, + { url = "https://files.pythonhosted.org/packages/3f/14/c3554d512d5f9100a95e737502f4a2323a1959f6d0d01e0d0997b35f7b10/MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", size = 17127 }, + { url = "https://files.pythonhosted.org/packages/f8/ff/2c942a82c35a49df5de3a630ce0a8456ac2969691b230e530ac12314364c/MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", size = 18192 }, + { url = "https://files.pythonhosted.org/packages/4f/14/6f294b9c4f969d0c801a4615e221c1e084722ea6114ab2114189c5b8cbe0/MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", size = 14072 }, + { url = "https://files.pythonhosted.org/packages/81/d4/fd74714ed30a1dedd0b82427c02fa4deec64f173831ec716da11c51a50aa/MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", size = 26928 }, + { url = "https://files.pythonhosted.org/packages/c7/bd/50319665ce81bb10e90d1cf76f9e1aa269ea6f7fa30ab4521f14d122a3df/MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", size = 26106 }, + { url = "https://files.pythonhosted.org/packages/4c/6f/f2b0f675635b05f6afd5ea03c094557bdb8622fa8e673387444fe8d8e787/MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68", size = 25781 }, + { url = "https://files.pythonhosted.org/packages/51/e0/393467cf899b34a9d3678e78961c2c8cdf49fb902a959ba54ece01273fb1/MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", size = 30518 }, + { url = "https://files.pythonhosted.org/packages/f6/02/5437e2ad33047290dafced9df741d9efc3e716b75583bbd73a9984f1b6f7/MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", size = 29669 }, + { url = "https://files.pythonhosted.org/packages/0e/7d/968284145ffd9d726183ed6237c77938c021abacde4e073020f920e060b2/MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", size = 29933 }, + { url = "https://files.pythonhosted.org/packages/bf/f3/ecb00fc8ab02b7beae8699f34db9357ae49d9f21d4d3de6f305f34fa949e/MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", size = 16656 }, + { url = "https://files.pythonhosted.org/packages/92/21/357205f03514a49b293e214ac39de01fadd0970a6e05e4bf1ddd0ffd0881/MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", size = 17206 }, + { url = "https://files.pythonhosted.org/packages/0f/31/780bb297db036ba7b7bbede5e1d7f1e14d704ad4beb3ce53fb495d22bc62/MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", size = 18193 }, + { url = "https://files.pythonhosted.org/packages/6c/77/d77701bbef72892affe060cdacb7a2ed7fd68dae3b477a8642f15ad3b132/MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", size = 14073 }, + { url = "https://files.pythonhosted.org/packages/d9/a7/1e558b4f78454c8a3a0199292d96159eb4d091f983bc35ef258314fe7269/MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", size = 26486 }, + { url = "https://files.pythonhosted.org/packages/5f/5a/360da85076688755ea0cceb92472923086993e86b5613bbae9fbc14136b0/MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", size = 25685 }, + { url = "https://files.pythonhosted.org/packages/6a/18/ae5a258e3401f9b8312f92b028c54d7026a97ec3ab20bfaddbdfa7d8cce8/MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", size = 25338 }, + { url = "https://files.pythonhosted.org/packages/0b/cc/48206bd61c5b9d0129f4d75243b156929b04c94c09041321456fd06a876d/MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", size = 30439 }, + { url = "https://files.pythonhosted.org/packages/d1/06/a41c112ab9ffdeeb5f77bc3e331fdadf97fa65e52e44ba31880f4e7f983c/MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", size = 29531 }, + { url = "https://files.pythonhosted.org/packages/02/8c/ab9a463301a50dab04d5472e998acbd4080597abc048166ded5c7aa768c8/MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", size = 29823 }, + { url = "https://files.pythonhosted.org/packages/bc/29/9bc18da763496b055d8e98ce476c8e718dcfd78157e17f555ce6dd7d0895/MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", size = 16658 }, + { url = "https://files.pythonhosted.org/packages/f6/f8/4da07de16f10551ca1f640c92b5f316f9394088b183c6a57183df6de5ae4/MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", size = 17211 }, +] + +[[package]] +name = "markupsafe" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.9'", +] +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357 }, + { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393 }, + { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732 }, + { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866 }, + { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964 }, + { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977 }, + { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366 }, + { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091 }, + { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065 }, + { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514 }, + { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353 }, + { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392 }, + { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984 }, + { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120 }, + { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032 }, + { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057 }, + { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359 }, + { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306 }, + { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094 }, + { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521 }, + { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274 }, + { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348 }, + { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149 }, + { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118 }, + { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993 }, + { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178 }, + { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319 }, + { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352 }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 }, + { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274 }, + { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352 }, + { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122 }, + { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085 }, + { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978 }, + { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208 }, + { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357 }, + { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344 }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 }, + { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510 }, + { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486 }, + { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480 }, + { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914 }, + { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796 }, + { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473 }, + { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114 }, + { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098 }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, + { url = "https://files.pythonhosted.org/packages/a7/ea/9b1530c3fdeeca613faeb0fb5cbcf2389d816072fab72a71b45749ef6062/MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a", size = 14344 }, + { url = "https://files.pythonhosted.org/packages/4b/c2/fbdbfe48848e7112ab05e627e718e854d20192b674952d9042ebd8c9e5de/MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff", size = 12389 }, + { url = "https://files.pythonhosted.org/packages/f0/25/7a7c6e4dbd4f867d95d94ca15449e91e52856f6ed1905d58ef1de5e211d0/MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13", size = 21607 }, + { url = "https://files.pythonhosted.org/packages/53/8f/f339c98a178f3c1e545622206b40986a4c3307fe39f70ccd3d9df9a9e425/MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144", size = 20728 }, + { url = "https://files.pythonhosted.org/packages/1a/03/8496a1a78308456dbd50b23a385c69b41f2e9661c67ea1329849a598a8f9/MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29", size = 20826 }, + { url = "https://files.pythonhosted.org/packages/e6/cf/0a490a4bd363048c3022f2f475c8c05582179bb179defcee4766fb3dcc18/MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0", size = 21843 }, + { url = "https://files.pythonhosted.org/packages/19/a3/34187a78613920dfd3cdf68ef6ce5e99c4f3417f035694074beb8848cd77/MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0", size = 21219 }, + { url = "https://files.pythonhosted.org/packages/17/d8/5811082f85bb88410ad7e452263af048d685669bbbfb7b595e8689152498/MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178", size = 20946 }, + { url = "https://files.pythonhosted.org/packages/7c/31/bd635fb5989440d9365c5e3c47556cfea121c7803f5034ac843e8f37c2f2/MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f", size = 15063 }, + { url = "https://files.pythonhosted.org/packages/b3/73/085399401383ce949f727afec55ec3abd76648d04b9f22e1c0e99cb4bec3/MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a", size = 15506 }, +] + +[[package]] +name = "mergedeep" +version = "1.3.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/41/580bb4006e3ed0361b8151a01d324fb03f420815446c7def45d02f74c270/mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", size = 4661 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354 }, +] + +[[package]] +name = "mkdocs" +version = "1.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "ghp-import" }, + { name = "importlib-metadata", version = "8.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, + { name = "importlib-metadata", version = "8.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.9.*'" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "markupsafe", version = "2.1.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, + { name = "markupsafe", version = "3.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, + { name = "mergedeep" }, + { name = "mkdocs-get-deps" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "pyyaml" }, + { name = "pyyaml-env-tag" }, + { name = "watchdog", version = "4.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, + { name = "watchdog", version = "6.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bc/c6/bbd4f061bd16b378247f12953ffcb04786a618ce5e904b8c5a01a0309061/mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", size = 3889159 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451 }, +] + +[[package]] +name = "mkdocs-gen-files" +version = "0.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mkdocs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/48/85/2d634462fd59136197d3126ca431ffb666f412e3db38fd5ce3a60566303e/mkdocs_gen_files-0.5.0.tar.gz", hash = "sha256:4c7cf256b5d67062a788f6b1d035e157fc1a9498c2399be9af5257d4ff4d19bc", size = 7539 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/0f/1e55b3fd490ad2cecb6e7b31892d27cb9fc4218ec1dab780440ba8579e74/mkdocs_gen_files-0.5.0-py3-none-any.whl", hash = "sha256:7ac060096f3f40bd19039e7277dd3050be9a453c8ac578645844d4d91d7978ea", size = 8380 }, +] + +[[package]] +name = "mkdocs-get-deps" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "importlib-metadata", version = "8.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, + { name = "importlib-metadata", version = "8.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.9.*'" }, + { name = "mergedeep" }, + { name = "platformdirs" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/f5/ed29cd50067784976f25ed0ed6fcd3c2ce9eb90650aa3b2796ddf7b6870b/mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c", size = 10239 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134", size = 9521 }, +] + +[[package]] +name = "mkdocs-git-authors-plugin" +version = "0.9.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mkdocs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/80/ef/09ab7178d580e342cb3ba279c48eaf3abf55795a2ae6e5426fe2c725143c/mkdocs_git_authors_plugin-0.9.2.tar.gz", hash = "sha256:77f97c321e08a8757beb866293eb257070b11cd5a080976bc6696b249cbade4f", size = 21403 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/08/57d0fea1cc30096fcc94ec9cd4ccdee625be89fd710626f78d90fc13738e/mkdocs_git_authors_plugin-0.9.2-py3-none-any.whl", hash = "sha256:f6cefc4dc832865d26f7f9f944c0a8c7dc852742d79320f3800e0d97814e2a84", size = 20332 }, +] + +[[package]] +name = "mkdocs-git-revision-date-localized-plugin" +source = { editable = "." } +dependencies = [ + { name = "babel" }, + { name = "gitpython" }, + { name = "mkdocs" }, + { name = "pytz" }, +] + +[package.dev-dependencies] +dev = [ + { name = "click" }, + { name = "codecov" }, + { name = "mkdocs-gen-files" }, + { name = "mkdocs-git-authors-plugin" }, + { name = "mkdocs-material" }, + { name = "mkdocs-monorepo-plugin" }, + { name = "mkdocs-static-i18n" }, + { name = "mkdocs-techdocs-core" }, + { name = "pytest" }, + { name = "pytest-cov", version = "5.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, + { name = "pytest-cov", version = "6.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [ + { name = "babel", specifier = ">=2.7.0" }, + { name = "gitpython", specifier = ">=3.1.44" }, + { name = "mkdocs", specifier = ">=1.0" }, + { name = "pytz", specifier = ">=2025.1" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "click", specifier = ">=8.1.8" }, + { name = "codecov", specifier = ">=2.1.13" }, + { name = "mkdocs-gen-files", specifier = ">=0.5.0" }, + { name = "mkdocs-git-authors-plugin", specifier = ">=0.9.2" }, + { name = "mkdocs-material", specifier = ">=9.6.7" }, + { name = "mkdocs-monorepo-plugin", specifier = ">=1.1.0" }, + { name = "mkdocs-static-i18n", specifier = ">=1.3.0" }, + { name = "mkdocs-techdocs-core" }, + { name = "pytest", specifier = ">=8.3.5" }, + { name = "pytest-cov", specifier = ">=5.0.0" }, + { name = "ruff" }, +] + +[[package]] +name = "mkdocs-material" +version = "9.6.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "backrefs", version = "5.7.post1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, + { name = "backrefs", version = "5.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, + { name = "colorama" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "mkdocs" }, + { name = "mkdocs-material-extensions" }, + { name = "paginate" }, + { name = "pygments" }, + { name = "pymdown-extensions" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/10/0a/17557708cfc6a11a1a941199b6b54a8990b297d910db81a43f1082b11e1b/mkdocs_material-9.6.8.tar.gz", hash = "sha256:8de31bb7566379802532b248bd56d9c4bc834afc4625884bf5769f9412c6a354", size = 3948078 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/fd/0e6aa44f5b4fb5a386f19c398222a6c75a313d52567ba992bad691cf0d80/mkdocs_material-9.6.8-py3-none-any.whl", hash = "sha256:0a51532dd8aa80b232546c073fe3ef60dfaef1b1b12196ac7191ee01702d1cf8", size = 8697857 }, +] + +[[package]] +name = "mkdocs-material-extensions" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/79/9b/9b4c96d6593b2a541e1cb8b34899a6d021d208bb357042823d4d2cabdbe7/mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", size = 11847 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728 }, +] + +[[package]] +name = "mkdocs-monorepo-plugin" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mkdocs" }, + { name = "python-slugify" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f7/6c/5b2a34fd63fe20724e2edf1879e977b40453efe40e1c385a05f38b420664/mkdocs-monorepo-plugin-1.1.0.tar.gz", hash = "sha256:ccc566e166aac5ae7fade498c15c4a337a4892d238629b51aba8ef3fc7099034", size = 13435 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d3/33/4cc6c70223aee511244f8fe7706df70d1cd253d1446ab466c73f9dfbaab5/mkdocs_monorepo_plugin-1.1.0-py3-none-any.whl", hash = "sha256:7bbfd9756a7fdecf64d6105dad96cce7e7bb5f0d6cfc2bfda31a1919c77cc3b9", size = 14312 }, +] + +[[package]] +name = "mkdocs-static-i18n" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mkdocs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/03/2b/59652a2550465fde25ae6a009cb6d74d0f7e724d272fc952685807b29ca1/mkdocs_static_i18n-1.3.0.tar.gz", hash = "sha256:65731e1e4ec6d719693e24fee9340f5516460b2b7244d2a89bed4ce3cfa6a173", size = 1370450 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/f7/ef222a7a2f96ecf79c7c00bfc9dde3b22cd2cc1bd2b7472c7b204fc64225/mkdocs_static_i18n-1.3.0-py3-none-any.whl", hash = "sha256:7905d52fff71d2c108b6c344fd223e848ca7e39ddf319b70864dfa47dba85d6b", size = 21660 }, +] + +[[package]] +name = "mkdocs-techdocs-core" +version = "0.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mkdocs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/56/03/e7fbf44586064a33fbe4a0ea868bd6d482688baeb6fa06a5dfa44ca17312/mkdocs-techdocs-core-0.0.3.tar.gz", hash = "sha256:b45bf3c240e8332d29ea275194cb4f4b26d22e1df505df4af219eeb3cc9bbafd", size = 3072 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/d7/7c3a9b6c216e06a751ed70440818b12e5e78fbfb87f02b147cfc21f12e0b/mkdocs_techdocs_core-0.0.3-py3-none-any.whl", hash = "sha256:56c35a852093a3422671cdeeb1eb169ed8e51348b5956e54b269815971fab9ce", size = 3058 }, +] + +[[package]] +name = "packaging" +version = "24.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, +] + +[[package]] +name = "paginate" +version = "0.5.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/46/68dde5b6bc00c1296ec6466ab27dddede6aec9af1b99090e1107091b3b84/paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", size = 19252 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746 }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 }, +] + +[[package]] +name = "platformdirs" +version = "4.3.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, +] + +[[package]] +name = "pygments" +version = "2.19.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293 }, +] + +[[package]] +name = "pymdown-extensions" +version = "10.14.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7c/44/e6de2fdc880ad0ec7547ca2e087212be815efbc9a425a8d5ba9ede602cbb/pymdown_extensions-10.14.3.tar.gz", hash = "sha256:41e576ce3f5d650be59e900e4ceff231e0aed2a88cf30acaee41e02f063a061b", size = 846846 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/f5/b9e2a42aa8f9e34d52d66de87941ecd236570c7ed2e87775ed23bbe4e224/pymdown_extensions-10.14.3-py3-none-any.whl", hash = "sha256:05e0bee73d64b9c71a4ae17c72abc2f700e8bc8403755a00580b49a4e9f189e9", size = 264467 }, +] + +[[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 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634 }, +] + +[[package]] +name = "pytest-cov" +version = "5.0.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.9'", +] +dependencies = [ + { name = "coverage", version = "7.6.1", source = { registry = "https://pypi.org/simple" }, extra = ["toml"], marker = "python_full_version < '3.9'" }, + { name = "pytest", marker = "python_full_version < '3.9'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/74/67/00efc8d11b630c56f15f4ad9c7f9223f1e5ec275aaae3fa9118c6a223ad2/pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857", size = 63042 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/3a/af5b4fa5961d9a1e6237b530eb87dd04aea6eb83da09d2a4073d81b54ccf/pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652", size = 21990 }, +] + +[[package]] +name = "pytest-cov" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.9'", +] +dependencies = [ + { name = "coverage", version = "7.6.12", source = { registry = "https://pypi.org/simple" }, extra = ["toml"], marker = "python_full_version >= '3.9'" }, + { name = "pytest", marker = "python_full_version >= '3.9'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/be/45/9b538de8cef30e17c7b45ef42f538a94889ed6a16f2387a6c89e73220651/pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0", size = 66945 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/3b/48e79f2cd6a61dbbd4807b4ed46cb564b4fd50a76166b1c4ea5c1d9e2371/pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35", size = 22949 }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, +] + +[[package]] +name = "python-slugify" +version = "8.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "text-unidecode" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/87/c7/5e1547c44e31da50a460df93af11a535ace568ef89d7a811069ead340c4a/python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856", size = 10921 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/62/02da182e544a51a5c3ccf4b03ab79df279f9c60c5e82d5e8bec7ca26ac11/python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8", size = 10051 }, +] + +[[package]] +name = "pytz" +version = "2025.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/57/df1c9157c8d5a05117e455d66fd7cf6dbc46974f832b1058ed4856785d8a/pytz-2025.1.tar.gz", hash = "sha256:c2db42be2a2518b28e65f9207c4d05e6ff547d1efa4086469ef855e4ab70178e", size = 319617 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/38/ac33370d784287baa1c3d538978b5e2ea064d4c1b93ffbd12826c190dd10/pytz-2025.1-py2.py3-none-any.whl", hash = "sha256:89dd22dca55b46eac6eda23b2d72721bf1bdfef212645d81513ef5d03038de57", size = 507930 }, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199 }, + { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758 }, + { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463 }, + { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280 }, + { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239 }, + { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802 }, + { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527 }, + { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052 }, + { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774 }, + { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612 }, + { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040 }, + { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829 }, + { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167 }, + { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952 }, + { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301 }, + { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638 }, + { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850 }, + { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980 }, + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, + { url = "https://files.pythonhosted.org/packages/74/d9/323a59d506f12f498c2097488d80d16f4cf965cee1791eab58b56b19f47a/PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a", size = 183218 }, + { url = "https://files.pythonhosted.org/packages/74/cc/20c34d00f04d785f2028737e2e2a8254e1425102e730fee1d6396f832577/PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5", size = 728067 }, + { url = "https://files.pythonhosted.org/packages/20/52/551c69ca1501d21c0de51ddafa8c23a0191ef296ff098e98358f69080577/PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d", size = 757812 }, + { url = "https://files.pythonhosted.org/packages/fd/7f/2c3697bba5d4aa5cc2afe81826d73dfae5f049458e44732c7a0938baa673/PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083", size = 746531 }, + { url = "https://files.pythonhosted.org/packages/8c/ab/6226d3df99900e580091bb44258fde77a8433511a86883bd4681ea19a858/PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706", size = 800820 }, + { url = "https://files.pythonhosted.org/packages/a0/99/a9eb0f3e710c06c5d922026f6736e920d431812ace24aae38228d0d64b04/PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a", size = 145514 }, + { url = "https://files.pythonhosted.org/packages/75/8a/ee831ad5fafa4431099aa4e078d4c8efd43cd5e48fbc774641d233b683a9/PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff", size = 162702 }, + { url = "https://files.pythonhosted.org/packages/65/d8/b7a1db13636d7fb7d4ff431593c510c8b8fca920ade06ca8ef20015493c5/PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d", size = 184777 }, + { url = "https://files.pythonhosted.org/packages/0a/02/6ec546cd45143fdf9840b2c6be8d875116a64076218b61d68e12548e5839/PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f", size = 172318 }, + { url = "https://files.pythonhosted.org/packages/0e/9a/8cc68be846c972bda34f6c2a93abb644fb2476f4dcc924d52175786932c9/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290", size = 720891 }, + { url = "https://files.pythonhosted.org/packages/e9/6c/6e1b7f40181bc4805e2e07f4abc10a88ce4648e7e95ff1abe4ae4014a9b2/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12", size = 722614 }, + { url = "https://files.pythonhosted.org/packages/3d/32/e7bd8535d22ea2874cef6a81021ba019474ace0d13a4819c2a4bce79bd6a/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19", size = 737360 }, + { url = "https://files.pythonhosted.org/packages/d7/12/7322c1e30b9be969670b672573d45479edef72c9a0deac3bb2868f5d7469/PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e", size = 699006 }, + { url = "https://files.pythonhosted.org/packages/82/72/04fcad41ca56491995076630c3ec1e834be241664c0c09a64c9a2589b507/PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725", size = 723577 }, + { url = "https://files.pythonhosted.org/packages/ed/5e/46168b1f2757f1fcd442bc3029cd8767d88a98c9c05770d8b420948743bb/PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631", size = 144593 }, + { url = "https://files.pythonhosted.org/packages/19/87/5124b1c1f2412bb95c59ec481eaf936cd32f0fe2a7b16b97b81c4c017a6a/PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8", size = 162312 }, +] + +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/8e/da1c6c58f751b70f8ceb1eb25bc25d524e8f14fe16edcce3f4e3ba08629c/pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb", size = 5631 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/66/bbb1dd374f5c870f59c5bb1db0e18cbe7fa739415a24cbd95b2d1f5ae0c4/pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069", size = 3911 }, +] + +[[package]] +name = "requests" +version = "2.32.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3", version = "2.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, + { name = "urllib3", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, +] + +[[package]] +name = "ruff" +version = "0.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/ec/9c59d2956566517c98ac8267554f4eaceafb2a19710a429368518b7fab43/ruff-0.10.0.tar.gz", hash = "sha256:fa1554e18deaf8aa097dbcfeafaf38b17a2a1e98fdc18f50e62e8a836abee392", size = 3789921 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/3f/742afe91b43def2a75990b293c676355576c0ff9cdbcf4249f78fa592544/ruff-0.10.0-py3-none-linux_armv6l.whl", hash = "sha256:46a2aa0eaae5048e5f804f0be9489d8a661633e23277b7293089e70d5c1a35c4", size = 10078369 }, + { url = "https://files.pythonhosted.org/packages/8d/a0/8696fb4862e82f7b40bbbc2917137594b22826cc62d77278a91391507514/ruff-0.10.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:775a6bc61af9dd0a2e1763406522a137e62aabb743d8b43ed95f019cdd1526c7", size = 10876912 }, + { url = "https://files.pythonhosted.org/packages/40/aa/0d48b7b7d7a1f168bb8fd893ed559d633c7d68c4a8ef9b996f0c2bd07aca/ruff-0.10.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8b03e6fcd39d20f0004f9956f0ed5eadc404d3a299f9d9286323884e3b663730", size = 10229962 }, + { url = "https://files.pythonhosted.org/packages/21/de/861ced2f75b045d8cfc038d68961d8ac117344df1f43a11abdd05bf7991b/ruff-0.10.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:621101d1af80248827f2409a78c8177c8319986a57b4663613b9c72f8617bfcd", size = 10404627 }, + { url = "https://files.pythonhosted.org/packages/21/69/666e0b840191c3ce433962c0d05fc0f6800afe259ea5d230cc731655d8e2/ruff-0.10.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e2dfe85cb6bfbd4259801e7d4982f2a72bdbd5749dc73a09d68a6dbf77f2209a", size = 9939383 }, + { url = "https://files.pythonhosted.org/packages/76/bf/34a2adc58092c99cdfa9f1303acd82d840d56412022e477e2ab20c261d2d/ruff-0.10.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43ac3879a20c22fdc57e559f0bb27f0c71828656841d0b42d3505b1e5b3a83c8", size = 11492269 }, + { url = "https://files.pythonhosted.org/packages/31/3d/f7ccfcf69f15948623b190feea9d411d5029ae39725fcc078f8d43bd07a6/ruff-0.10.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ef5e3aac421bbc62f8a7aab21edd49a359ed42205f7a5091a74386bca1efa293", size = 12186939 }, + { url = "https://files.pythonhosted.org/packages/6e/3e/c557c0abfdea85c7d238a3cb238c73e7b6d17c30a584234c4fd8fe2cafb6/ruff-0.10.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9f4f62d7fac8b748fce67ad308116b4d4cc1a9f964b4804fc5408fbd06e13ba9", size = 11655896 }, + { url = "https://files.pythonhosted.org/packages/3b/8e/3bfa110f37e5192eb3943f14943d05fbb9a76fea380aa87655e6f6276a54/ruff-0.10.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:02f9f6205c5b0d626f98da01a0e75b724a64c21c554bba24b12522c9e9ba6a04", size = 13885502 }, + { url = "https://files.pythonhosted.org/packages/51/4a/22cdab59b5563dd7f4c504d0f1e6bb25fc800a5a057395bc24f8ff3a85b2/ruff-0.10.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46a97f3d55f68464c48d1e929a8582c7e5bb80ac73336bbc7b0da894d8e6cd9e", size = 11344767 }, + { url = "https://files.pythonhosted.org/packages/3d/0f/8f85de2ac565f82f47c6d8fb7ae04383e6300560f2d1b91c1268ff91e507/ruff-0.10.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a0b811197d0dc96c13d610f8cfdc56030b405bcff5c2f10eab187b329da0ca4a", size = 10300331 }, + { url = "https://files.pythonhosted.org/packages/90/4a/b337df327832cb30bd8607e8d1fdf1b6b5ca228307d5008dd49028fb66ae/ruff-0.10.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a13a3fda0870c1c964b47ff5d73805ae80d2a9de93ee2d185d453b8fddf85a84", size = 9926551 }, + { url = "https://files.pythonhosted.org/packages/d7/e9/141233730b85675ac806c4b62f70516bd9c0aae8a55823f3a6589ed411be/ruff-0.10.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6ceb8d9f062e90ddcbad929f6136edf764bbf6411420a07e8357602ea28cd99f", size = 10925061 }, + { url = "https://files.pythonhosted.org/packages/24/09/02987935b55c2d353a226ac1b4f9718830e2e195834929f46c07eeede746/ruff-0.10.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c41d07d573617ed2f287ea892af2446fd8a8d877481e8e1ba6928e020665d240", size = 11394949 }, + { url = "https://files.pythonhosted.org/packages/d6/ec/054f9879fb6f4122d43ffe5c9f88c8c323a9cd14220d5c813aea5805e02c/ruff-0.10.0-py3-none-win32.whl", hash = "sha256:76e2de0cbdd587e373cd3b4050d2c45babdd7014c1888a6f121c29525c748a15", size = 10272077 }, + { url = "https://files.pythonhosted.org/packages/6e/49/915d8682f24645b904fe6a1aac36101464fc814923fdf293c1388dc5533c/ruff-0.10.0-py3-none-win_amd64.whl", hash = "sha256:f943acdecdcc6786a8d1dad455dd9f94e6d57ccc115be4993f9b52ef8316027a", size = 11393300 }, + { url = "https://files.pythonhosted.org/packages/82/ed/5c59941634c9026ceeccc7c119f23f4356f09aafd28c15c1bc734ac66b01/ruff-0.10.0-py3-none-win_arm64.whl", hash = "sha256:935a943bdbd9ff0685acd80d484ea91088e27617537b5f7ef8907187d19d28d0", size = 10510133 }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, +] + +[[package]] +name = "smmap" +version = "5.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/44/cd/a040c4b3119bbe532e5b0732286f805445375489fceaec1f48306068ee3b/smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5", size = 22329 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e", size = 24303 }, +] + +[[package]] +name = "text-unidecode" +version = "1.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ab/e2/e9a00f0ccb71718418230718b3d900e71a5d16e701a3dae079a21e9cd8f8/text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93", size = 76885 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/a5/c0b6468d3824fe3fde30dbb5e1f687b291608f9473681bbf7dabbf5a87d7/text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8", size = 78154 }, +] + +[[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 } +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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, +] + +[[package]] +name = "urllib3" +version = "2.2.3" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.9'", +] +sdist = { url = "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", size = 300677 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", size = 126338 }, +] + +[[package]] +name = "urllib3" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.9'", +] +sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 }, +] + +[[package]] +name = "watchdog" +version = "4.0.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.9'", +] +sdist = { url = "https://files.pythonhosted.org/packages/4f/38/764baaa25eb5e35c9a043d4c4588f9836edfe52a708950f4b6d5f714fd42/watchdog-4.0.2.tar.gz", hash = "sha256:b4dfbb6c49221be4535623ea4474a4d6ee0a9cef4a80b20c28db4d858b64e270", size = 126587 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/b0/219893d41c16d74d0793363bf86df07d50357b81f64bba4cb94fe76e7af4/watchdog-4.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ede7f010f2239b97cc79e6cb3c249e72962404ae3865860855d5cbe708b0fd22", size = 100257 }, + { url = "https://files.pythonhosted.org/packages/6d/c6/8e90c65693e87d98310b2e1e5fd7e313266990853b489e85ce8396cc26e3/watchdog-4.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a2cffa171445b0efa0726c561eca9a27d00a1f2b83846dbd5a4f639c4f8ca8e1", size = 92249 }, + { url = "https://files.pythonhosted.org/packages/6f/cd/2e306756364a934532ff8388d90eb2dc8bb21fe575cd2b33d791ce05a02f/watchdog-4.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c50f148b31b03fbadd6d0b5980e38b558046b127dc483e5e4505fcef250f9503", size = 92888 }, + { url = "https://files.pythonhosted.org/packages/de/78/027ad372d62f97642349a16015394a7680530460b1c70c368c506cb60c09/watchdog-4.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7c7d4bf585ad501c5f6c980e7be9c4f15604c7cc150e942d82083b31a7548930", size = 100256 }, + { url = "https://files.pythonhosted.org/packages/59/a9/412b808568c1814d693b4ff1cec0055dc791780b9dc947807978fab86bc1/watchdog-4.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:914285126ad0b6eb2258bbbcb7b288d9dfd655ae88fa28945be05a7b475a800b", size = 92252 }, + { url = "https://files.pythonhosted.org/packages/04/57/179d76076cff264982bc335dd4c7da6d636bd3e9860bbc896a665c3447b6/watchdog-4.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:984306dc4720da5498b16fc037b36ac443816125a3705dfde4fd90652d8028ef", size = 92888 }, + { url = "https://files.pythonhosted.org/packages/92/f5/ea22b095340545faea37ad9a42353b265ca751f543da3fb43f5d00cdcd21/watchdog-4.0.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1cdcfd8142f604630deef34722d695fb455d04ab7cfe9963055df1fc69e6727a", size = 100342 }, + { url = "https://files.pythonhosted.org/packages/cb/d2/8ce97dff5e465db1222951434e3115189ae54a9863aef99c6987890cc9ef/watchdog-4.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d7ab624ff2f663f98cd03c8b7eedc09375a911794dfea6bf2a359fcc266bff29", size = 92306 }, + { url = "https://files.pythonhosted.org/packages/49/c4/1aeba2c31b25f79b03b15918155bc8c0b08101054fc727900f1a577d0d54/watchdog-4.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:132937547a716027bd5714383dfc40dc66c26769f1ce8a72a859d6a48f371f3a", size = 92915 }, + { url = "https://files.pythonhosted.org/packages/79/63/eb8994a182672c042d85a33507475c50c2ee930577524dd97aea05251527/watchdog-4.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:cd67c7df93eb58f360c43802acc945fa8da70c675b6fa37a241e17ca698ca49b", size = 100343 }, + { url = "https://files.pythonhosted.org/packages/ce/82/027c0c65c2245769580605bcd20a1dc7dfd6c6683c8c4e2ef43920e38d27/watchdog-4.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcfd02377be80ef3b6bc4ce481ef3959640458d6feaae0bd43dd90a43da90a7d", size = 92313 }, + { url = "https://files.pythonhosted.org/packages/2a/89/ad4715cbbd3440cb0d336b78970aba243a33a24b1a79d66f8d16b4590d6a/watchdog-4.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:980b71510f59c884d684b3663d46e7a14b457c9611c481e5cef08f4dd022eed7", size = 92919 }, + { url = "https://files.pythonhosted.org/packages/55/08/1a9086a3380e8828f65b0c835b86baf29ebb85e5e94a2811a2eb4f889cfd/watchdog-4.0.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:aa160781cafff2719b663c8a506156e9289d111d80f3387cf3af49cedee1f040", size = 100255 }, + { url = "https://files.pythonhosted.org/packages/6c/3e/064974628cf305831f3f78264800bd03b3358ec181e3e9380a36ff156b93/watchdog-4.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f6ee8dedd255087bc7fe82adf046f0b75479b989185fb0bdf9a98b612170eac7", size = 92257 }, + { url = "https://files.pythonhosted.org/packages/23/69/1d2ad9c12d93bc1e445baa40db46bc74757f3ffc3a3be592ba8dbc51b6e5/watchdog-4.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0b4359067d30d5b864e09c8597b112fe0a0a59321a0f331498b013fb097406b4", size = 92886 }, + { url = "https://files.pythonhosted.org/packages/68/eb/34d3173eceab490d4d1815ba9a821e10abe1da7a7264a224e30689b1450c/watchdog-4.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:770eef5372f146997638d737c9a3c597a3b41037cfbc5c41538fc27c09c3a3f9", size = 100254 }, + { url = "https://files.pythonhosted.org/packages/18/a1/4bbafe7ace414904c2cc9bd93e472133e8ec11eab0b4625017f0e34caad8/watchdog-4.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eeea812f38536a0aa859972d50c76e37f4456474b02bd93674d1947cf1e39578", size = 92249 }, + { url = "https://files.pythonhosted.org/packages/f3/11/ec5684e0ca692950826af0de862e5db167523c30c9cbf9b3f4ce7ec9cc05/watchdog-4.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b2c45f6e1e57ebb4687690c05bc3a2c1fb6ab260550c4290b8abb1335e0fd08b", size = 92891 }, + { url = "https://files.pythonhosted.org/packages/3b/9a/6f30f023324de7bad8a3eb02b0afb06bd0726003a3550e9964321315df5a/watchdog-4.0.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:10b6683df70d340ac3279eff0b2766813f00f35a1d37515d2c99959ada8f05fa", size = 91775 }, + { url = "https://files.pythonhosted.org/packages/87/62/8be55e605d378a154037b9ba484e00a5478e627b69c53d0f63e3ef413ba6/watchdog-4.0.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f7c739888c20f99824f7aa9d31ac8a97353e22d0c0e54703a547a218f6637eb3", size = 92255 }, + { url = "https://files.pythonhosted.org/packages/6b/59/12e03e675d28f450bade6da6bc79ad6616080b317c472b9ae688d2495a03/watchdog-4.0.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c100d09ac72a8a08ddbf0629ddfa0b8ee41740f9051429baa8e31bb903ad7508", size = 91682 }, + { url = "https://files.pythonhosted.org/packages/ef/69/241998de9b8e024f5c2fbdf4324ea628b4231925305011ca8b7e1c3329f6/watchdog-4.0.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:f5315a8c8dd6dd9425b974515081fc0aadca1d1d61e078d2246509fd756141ee", size = 92249 }, + { url = "https://files.pythonhosted.org/packages/70/3f/2173b4d9581bc9b5df4d7f2041b6c58b5e5448407856f68d4be9981000d0/watchdog-4.0.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:2d468028a77b42cc685ed694a7a550a8d1771bb05193ba7b24006b8241a571a1", size = 91773 }, + { url = "https://files.pythonhosted.org/packages/f0/de/6fff29161d5789048f06ef24d94d3ddcc25795f347202b7ea503c3356acb/watchdog-4.0.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f15edcae3830ff20e55d1f4e743e92970c847bcddc8b7509bcd172aa04de506e", size = 92250 }, + { url = "https://files.pythonhosted.org/packages/8a/b1/25acf6767af6f7e44e0086309825bd8c098e301eed5868dc5350642124b9/watchdog-4.0.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:936acba76d636f70db8f3c66e76aa6cb5136a936fc2a5088b9ce1c7a3508fc83", size = 82947 }, + { url = "https://files.pythonhosted.org/packages/e8/90/aebac95d6f954bd4901f5d46dcd83d68e682bfd21798fd125a95ae1c9dbf/watchdog-4.0.2-py3-none-manylinux2014_armv7l.whl", hash = "sha256:e252f8ca942a870f38cf785aef420285431311652d871409a64e2a0a52a2174c", size = 82942 }, + { url = "https://files.pythonhosted.org/packages/15/3a/a4bd8f3b9381824995787488b9282aff1ed4667e1110f31a87b871ea851c/watchdog-4.0.2-py3-none-manylinux2014_i686.whl", hash = "sha256:0e83619a2d5d436a7e58a1aea957a3c1ccbf9782c43c0b4fed80580e5e4acd1a", size = 82947 }, + { url = "https://files.pythonhosted.org/packages/09/cc/238998fc08e292a4a18a852ed8274159019ee7a66be14441325bcd811dfd/watchdog-4.0.2-py3-none-manylinux2014_ppc64.whl", hash = "sha256:88456d65f207b39f1981bf772e473799fcdc10801062c36fd5ad9f9d1d463a73", size = 82946 }, + { url = "https://files.pythonhosted.org/packages/80/f1/d4b915160c9d677174aa5fae4537ae1f5acb23b3745ab0873071ef671f0a/watchdog-4.0.2-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:32be97f3b75693a93c683787a87a0dc8db98bb84701539954eef991fb35f5fbc", size = 82947 }, + { url = "https://files.pythonhosted.org/packages/db/02/56ebe2cf33b352fe3309588eb03f020d4d1c061563d9858a9216ba004259/watchdog-4.0.2-py3-none-manylinux2014_s390x.whl", hash = "sha256:c82253cfc9be68e3e49282831afad2c1f6593af80c0daf1287f6a92657986757", size = 82944 }, + { url = "https://files.pythonhosted.org/packages/01/d2/c8931ff840a7e5bd5dcb93f2bb2a1fd18faf8312e9f7f53ff1cf76ecc8ed/watchdog-4.0.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:c0b14488bd336c5b1845cee83d3e631a1f8b4e9c5091ec539406e4a324f882d8", size = 82947 }, + { url = "https://files.pythonhosted.org/packages/d0/d8/cdb0c21a4a988669d7c210c75c6a2c9a0e16a3b08d9f7e633df0d9a16ad8/watchdog-4.0.2-py3-none-win32.whl", hash = "sha256:0d8a7e523ef03757a5aa29f591437d64d0d894635f8a50f370fe37f913ce4e19", size = 82935 }, + { url = "https://files.pythonhosted.org/packages/99/2e/b69dfaae7a83ea64ce36538cc103a3065e12c447963797793d5c0a1d5130/watchdog-4.0.2-py3-none-win_amd64.whl", hash = "sha256:c344453ef3bf875a535b0488e3ad28e341adbd5a9ffb0f7d62cefacc8824ef2b", size = 82934 }, + { url = "https://files.pythonhosted.org/packages/b0/0b/43b96a9ecdd65ff5545b1b13b687ca486da5c6249475b1a45f24d63a1858/watchdog-4.0.2-py3-none-win_ia64.whl", hash = "sha256:baececaa8edff42cd16558a639a9b0ddf425f93d892e8392a56bf904f5eff22c", size = 82933 }, +] + +[[package]] +name = "watchdog" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.9'", +] +sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/56/90994d789c61df619bfc5ce2ecdabd5eeff564e1eb47512bd01b5e019569/watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26", size = 96390 }, + { url = "https://files.pythonhosted.org/packages/55/46/9a67ee697342ddf3c6daa97e3a587a56d6c4052f881ed926a849fcf7371c/watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112", size = 88389 }, + { url = "https://files.pythonhosted.org/packages/44/65/91b0985747c52064d8701e1075eb96f8c40a79df889e59a399453adfb882/watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3", size = 89020 }, + { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393 }, + { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392 }, + { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019 }, + { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471 }, + { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449 }, + { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054 }, + { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480 }, + { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451 }, + { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057 }, + { url = "https://files.pythonhosted.org/packages/05/52/7223011bb760fce8ddc53416beb65b83a3ea6d7d13738dde75eeb2c89679/watchdog-6.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e6f0e77c9417e7cd62af82529b10563db3423625c5fce018430b249bf977f9e8", size = 96390 }, + { url = "https://files.pythonhosted.org/packages/9c/62/d2b21bc4e706d3a9d467561f487c2938cbd881c69f3808c43ac1ec242391/watchdog-6.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:90c8e78f3b94014f7aaae121e6b909674df5b46ec24d6bebc45c44c56729af2a", size = 88386 }, + { url = "https://files.pythonhosted.org/packages/ea/22/1c90b20eda9f4132e4603a26296108728a8bfe9584b006bd05dd94548853/watchdog-6.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e7631a77ffb1f7d2eefa4445ebbee491c720a5661ddf6df3498ebecae5ed375c", size = 89017 }, + { url = "https://files.pythonhosted.org/packages/30/ad/d17b5d42e28a8b91f8ed01cb949da092827afb9995d4559fd448d0472763/watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", size = 87902 }, + { url = "https://files.pythonhosted.org/packages/5c/ca/c3649991d140ff6ab67bfc85ab42b165ead119c9e12211e08089d763ece5/watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", size = 88380 }, + { url = "https://files.pythonhosted.org/packages/5b/79/69f2b0e8d3f2afd462029031baafb1b75d11bb62703f0e1022b2e54d49ee/watchdog-6.0.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7a0e56874cfbc4b9b05c60c8a1926fedf56324bb08cfbc188969777940aef3aa", size = 87903 }, + { url = "https://files.pythonhosted.org/packages/e2/2b/dc048dd71c2e5f0f7ebc04dd7912981ec45793a03c0dc462438e0591ba5d/watchdog-6.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6439e374fc012255b4ec786ae3c4bc838cd7309a540e5fe0952d03687d8804e", size = 88381 }, + { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079 }, + { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078 }, + { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076 }, + { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077 }, + { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078 }, + { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077 }, + { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078 }, + { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065 }, + { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070 }, + { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067 }, +] + +[[package]] +name = "zipp" +version = "3.20.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.9'", +] +sdist = { url = "https://files.pythonhosted.org/packages/54/bf/5c0000c44ebc80123ecbdddba1f5dcd94a5ada602a9c225d84b5aaa55e86/zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29", size = 24199 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/8b/5ba542fa83c90e09eac972fc9baca7a88e7e7ca4b221a89251954019308b/zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", size = 9200 }, +] + +[[package]] +name = "zipp" +version = "3.21.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.9'", +] +sdist = { url = "https://files.pythonhosted.org/packages/3f/50/bad581df71744867e9468ebd0bcd6505de3b275e06f202c2cb016e3ff56f/zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4", size = 24545 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/1a/7e4798e9339adc931158c9d69ecc34f5e6791489d469f5e50ec15e35f458/zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931", size = 9630 }, +]