From 82cbea5da61972fbe81fbf455b0563ce6b2099f7 Mon Sep 17 00:00:00 2001 From: gsv Date: Wed, 16 Sep 2026 14:59:48 +0300 Subject: [PATCH 001/277] docs(36-S1): record task 36 in the task log and write the detailed plan Task 36 documents the release experience gained while cutting v5.0.0 (task 35), split per the user's instruction: global knowledge useful for all developers goes to docs/release.rst, agent-local operational knowledge (pre-tag gate, verification, recovery procedures) goes to the release skill. The plan records the full knowledge-split decision so the docs/skill boundary is auditable. The task 35 line gains the five user-guidance quotes given during the release run (actions update, CI warning fix, TestPyPI-on-PR request, trusted-publisher question, safe-to-merge question), verbatim. --- tasks/detailed_plan.md | 230 ++++++++++++++++------------------------- tasks/tasks.md | 3 +- 2 files changed, 93 insertions(+), 140 deletions(-) diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index 53a868fe..6ca7d9c6 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -1,164 +1,116 @@ -# Task 35: Cut the v5.0.0 release +# Task 36: Document the release experience (global → docs, local → skill) ## Context -Task 34 finalized the `[Unreleased]` changelog section with issue references. -This task cuts the release. The procedure is codified in the `release` skill -and `docs/release.rst` (single source of truth — not re-described here); this -plan records only what is specific to this run. - -## Verified facts (2026-09-16, on `dev`) - -- Version is already `5.0.0` in `cfpq_data/config.py` and `pyproject.toml`; - `utils/bump_version.py 5.0.0` only promotes the changelog section. -- The dataset is already served from `5.0.0/graph/` — no re-upload needed. -- Trusted Publishing for PyPI was configured by the user (repository - `FormalLanguageConstrainedPathQuerying/CFPQ_Data`, workflow `publish.yml`). -- The changelog line "The changes below make up the upcoming **5.0.0** - release." must be dropped before promotion: after the bump it would sit - under the released `[5.0.0]` heading and leak into the GitHub Release notes - (extracted by `publish.yml` from the `## [5.0.0]` section). - -## Human gates (user guidance, verbatim in tasks.md) - -1. The user reviews and merges the `dev` -> `master` PR manually. No tag is - created and nothing is pushed to `master` before the user confirms the - merge. -2. The tag is created on `origin/master` after a fresh `git fetch origin`, so - it points at the merged commit. +Task 35 cut v5.0.0 and surfaced a series of release-flow incidents (intersphinx +network flake, missing MANIFEST.in, TestPyPI PR check via OIDC Trusted +Publishing, the `/legacy/` TestPyPI upload URL, the missing checkout in the +`publish-pypi` job). The user asks that all experience and knowledge on +releases be documented so the next release is fast and smooth, and requires a +strict split: + +- **Global knowledge** — useful for all developers — lives in `docs/` + (the model: "What" and "Why"). +- **Local knowledge** — agent-specific operational details (commands, + pitfalls, procedures) — lives in the `release` skill (the "How"), which + stays a thin pointer to the docs. + +## Knowledge split (decision record) + +Global → `docs/release.rst` (facts any developer of the project needs): + +- The sdist-completeness constraint: `python -m build` builds the wheel from + the sdist, so the sdist must contain everything `setup.py` reads at build + time (`requirements/*.txt`, included via `MANIFEST.in`). +- PyPI and TestPyPI reject re-uploads of files that already exist for a + version; the PR check uses `skip-existing`; if a tag push reaches PyPI and + then fails, an owner must delete the release before the tag can be + re-pushed. +- Merging a pull request into `master` never publishes: the workflow runs + only on `v*` tag pushes (the merge does redeploy the docs site). + +Local → `.opencode/skills/release/SKILL.md` (agent operations only): + +- Pre-tag gate: wait for the PR's Publish check (TestPyPI pre-publish) to pass + before asking the user to merge and before tagging. +- Human merge gate: the user reviews and merges the PR manually; tag + push + only after the user confirms the merge (tag on `origin/master` after a fresh + `git fetch origin`). +- Verification of both PyPI and the GitHub Release page (changelog notes + + dist assets). +- Recovery procedures: workflow failure before the PyPI publish (delete the + tag, fix, merge, re-tag) and after it (an owner deletes the PyPI release + first — the fact lives in the docs; create the GitHub Release manually via + the API, including the `upload_url` asset-upload quirk). +- Machine notes: no `gh` CLI on this machine — use curl + the GitHub API with + the token extracted from the remote URL (never echoed). + +Not documented here (implementation details readable in +`.github/workflows/publish.yml` itself): the checkout step of `publish-pypi`, +the `/legacy/` TestPyPI repository URL, action versions. ## Subtasks -### S1: Write this detailed plan +### S1: Record task 36 in the task log and write this detailed plan **Code:** none (documentation-only) **Tests:** skip — no code to test -**Docs:** `tasks/detailed_plan.md` - -**Spec:** Record context, verified facts, human gates, and subtasks S2-S5. - -### S2: Finalize the changelog and promote it to [5.0.0] - -**Code:** none (runs the existing `utils/bump_version.py`) -**Tests:** skip — no code changes; the version guard is verified explicitly -**Docs:** `CHANGELOG.md` (drop the "upcoming" line; section promoted by the - helper) +**Docs:** `tasks/tasks.md` (task 36 line; the session's user guidance appended + verbatim to the task 35 line), `tasks/detailed_plan.md` **Spec:** -- Remove the "The changes below make up the upcoming **5.0.0** release." line. -- Run `python utils/bump_version.py 5.0.0`; it promotes `[Unreleased]` to - `## [5.0.0] - ` and inserts a fresh empty `[Unreleased]`. -- Verify `poetry run pre-commit run check-version-sync --all-files` passes. -- Commit on `dev` with the release-skill message: `chore: release 5.0.0`. +- Add the task 36 line with the user's exact wording and the split + instruction as `[USER GUIDANCE]`. +- Append, verbatim, the five user-guidance quotes given during task 35 + (actions update, CI warning fix, TestPyPI-on-PR request, trusted-publisher + question, safe-to-merge question) to the task 35 line. +- Replace `tasks/detailed_plan.md` with this plan. -### S3: Push dev and open the release PR (human gate after) +### S2: Record the global release knowledge in docs/release.rst **Code:** none -**Tests:** skip -**Docs:** none +**Tests:** skip — docs only; verified by the clean docs build and link check + in the quality gate +**Docs:** `docs/release.rst` ("Package publishing (automated)" section) **Spec:** -- `git push origin dev` (release exception to the no-push convention). -- Open a PR `dev` -> `master` via `gh pr create` with a title/body describing - the v5.0.0 release; do not merge it. -- STOP and ask the user to review and merge the PR manually. Do not proceed - to S4 before the user confirms the merge. +- Commit the drafted additions already present in the working tree: the two + packaging constraints (sdist completeness via `MANIFEST.in`; re-upload + rejection and its consequence for re-pushing a tag) and the "merging never + publishes" paragraph. +- Review them against the actual `publish.yml` behavior before committing; do + not restate agent procedures here — those belong to the skill. -### S4: Tag the merged commit and push the tag +### S3: Record the local release knowledge in the release skill **Code:** none -**Tests:** skip -**Docs:** none +**Tests:** skip — skill only +**Docs:** `.opencode/skills/release/SKILL.md` **Spec:** -- Only after the user confirms the PR is merged: `git fetch origin`. -- `git tag -a v5.0.0 -m "Release v5.0.0" origin/master` — the tag points at - the merged commit on `origin/master`, never at a local ref. -- `git push origin v5.0.0`. This triggers the `publish` workflow. - -### S5: Verify the publish and mark the task done +- Procedure: step 4 gains the pre-tag gate (the PR's Publish check must pass) + and the human merge gate (the user merges manually; proceed only after + confirmation); step 6's verification extends to the GitHub Release page + (changelog notes + dist assets), not just PyPI. +- New "Recovery" section: (a) workflow failure before the PyPI publish — + delete the tag, fix, merge the fix, re-tag on the new `origin/master`; + (b) failure after the PyPI publish — an owner deletes the PyPI release + first (reference `docs/release.rst` for the fact, do not re-describe it), + then create the GitHub Release manually via the API with the exact working + commands: token from the remote URL (never echoed), `awk` extraction of the + `[X.Y.Z]` changelog section, `POST /releases`, asset upload via the + created release's `upload_url` (`uploads.github.com`) — posting to + `api.github.com/.../releases/{id}/assets` returns 404. +- Notes: the `gh` CLI is not installed on this machine — use curl + the + GitHub API. +- Keep the skill a thin pointer: facts already in `docs/release.rst` are + referenced, never re-described. + +### S4: Mark task 36 done in the task log **Code:** none **Tests:** skip -**Docs:** `tasks/tasks.md` (mark task 35 done) +**Docs:** `tasks/tasks.md` -**Spec:** -- Watch the `publish` workflow run (tag verification, build, PyPI publish via - Trusted Publishing, GitHub Release creation). -- Verify the package is live on PyPI and the GitHub Release carries the - `[5.0.0]` changelog section. -- Prepend `[done] ` to the task 35 line in `tasks/tasks.md` (local commit on - `dev`; pushed with the next dev push — the release itself is already out). - -### S6: Make intersphinx inventory fetches resilient to transient network errors - -Added 2026-09-16 at the merge gate (user: "CI report set of warnings ... Fix -it"). The first CI run on `20a181a` failed its Docs build because the runner's -connection to `networkx.org` was reset while fetching the intersphinx -inventory; with the inventory missing, every `nx.MultiDiGraph` cross-reference -went unresolved and failed the build under the no-warnings policy. A second -run of the same commit passed — the failure was a transient network flake, not -a docs defect. - -**Code:** `docs/conf.py` (retry wrapper around `sphinx.util.requests.get`) -**Tests:** skip — build configuration only; verified by a clean docs build -**Docs:** `docs/developer.rst` ("Docs build and deploy" section) - -**Spec:** -- Retry only transient connection errors (`ConnectionError`, `Timeout`); a - final failure propagates, so the warning still fires and the build still - fails — no suppression. -- Note the behavior in the "Docs build and deploy" section of - `docs/developer.rst`. - -### S7: Fix sdist packaging so `python -m build` succeeds - -Added 2026-09-16 at the publish gate. The first real `python -m build` run -(publish workflow on tag `v5.0.0`) failed: `setup.py` reads -`requirements/*.txt`, but no MANIFEST.in existed, so the files were missing -from the sdist and the sdist→wheel step raised FileNotFoundError. This is the -first packaging build in the project's history — it was never exercised -before. - -**Code:** `MANIFEST.in` (new: `include requirements/*.txt`) -**Tests:** skip — verified with an isolated `python -m build` (clean venv, -same as CI); sdist contains all four requirements files and the wheel builds. -**Docs:** none - -### S8: Publish to TestPyPI on every PR targeting master - -Added 2026-09-16 at the merge gate (user request: validate publishing -automatically before the human merge). The `publish` workflow gains a -`pull_request: branches: [master]` trigger; the `publish-testpypi` job runs on -PRs with `skip-existing: true` because concurrent PRs share one package -version and TestPyPI rejects re-uploads of existing files. - -Final design (after the first PR run failed): TestPyPI uses **OIDC Trusted -Publishing**, not a token — the first run proved the pypi-publish action -silently falls back to OIDC when no token secret exists, and the user prefers -no long-lived secrets (consistent with the PyPI setup). The publisher's -subject claim is `repo:FormalLanguageConstrainedPathQuerying/CFPQ_Data:pull_request` -(the documented sub for pull_request events; confirmed in the failed run's -claims dump). The manual `workflow_dispatch` TestPyPI path was removed: its -sub claim cannot match the PR publisher, and the PR check fully covers -pre-release validation (a tag always points at a merged PR's head). - -**Code:** `.github/workflows/publish.yml` -**Tests:** skip — workflow-only; the build step is the check itself -**Docs:** `docs/release.rst` (Package publishing section), `CHANGELOG.md` - -### S9: Check out the repo in the publish-pypi job - -Added 2026-09-16 at the publish gate. The real tag push published to PyPI -successfully, but "Create GitHub Release" failed with -`awk: fatal: cannot open file 'CHANGELOG.md'`: the `publish-pypi` job never -checked out the repository (it only downloads the dist artifact), so the -changelog was absent from its working directory. Latent bug — the step had -never run before because every earlier attempt died upstream. The v5.0.0 -GitHub Release was created manually (same notes + the exact PyPI artifacts as -assets) while this fix lands via PR for future releases. - -**Code:** `.github/workflows/publish.yml` (`actions/checkout@v7` in -`publish-pypi`) -**Tests:** skip — workflow-only -**Docs:** none +**Spec:** After code review, the quality gate, and the merge to `dev`, +prepend `[done] ` to the task 36 line (commit on `dev`). diff --git a/tasks/tasks.md b/tasks/tasks.md index d107db12..e982327b 100644 --- a/tasks/tasks.md +++ b/tasks/tasks.md @@ -34,4 +34,5 @@ - [done] Task 32: Cool. Yes, fix Babel warnings. Analyze rest warnings. E.g. why you suppress aernings refs.citations and ref.footnote? Can we fix it and other warnings? I want to set warings as errors and go to 'no warnings policy'. Without suppresuins if possible. **[USER GUIDANCE]**: "Well. Try to find solution that does not require workarounds or checkers modification. If site o code refactoring required for this way, propose it to me. It may be easier to do smoll refactoring, rather than add workaround. If refactoring improve and simplify site and code, it is better that wotkaround or tooling patching." / "9 approved. Go." - [done] Task 33: Check developer documantation. Check that all parts of issue https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/76 well-documented, necessary parts added to README. **[USER GUIDANCE]**: "Let use docs as the source of truth, skills as thin pointers. Add this to main pronciples for future skills design and update." - [done] Task 34: Prepare v5.0.0 release (1/2): analyze the code with respect to the issues https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/122 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/76 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/75 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/74 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/28 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/26 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/16 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/2 and add respective references to the Changelog for the resolved ones. **[USER GUIDANCE]**: "Reference partial, no close claim" (issue #2: only the Zheng & Rugina C alias analysis data is in; the Vedurada 'Batch Alias Analysis' data is missing) / "Reference resolved sub-items only" (umbrella issue #28: cite the resolved sub-issues #27, #32, #20, #30, #33, #26 individually; do not claim #28 done). -- [done] Task 35: Prepare v5.0.0 release (2/2): cut the v5.0.0 release per the release skill (bump_version, PR dev->master, tag on origin/master, push, verify PyPI + GitHub Release). **[USER GUIDANCE]**: "Yes, both tasks. But do not forget to ask me to assist with access to PyPI. Guide me step-by-step. And do not forget that I must review and merge requext to master manually, so, tag + push and PyPI/GitHub release only after I confirm that requies merged. Moreover you should pull master irst to create tag on respective commit." / "Trusted publisher added. Go." +- [done] Task 35: Prepare v5.0.0 release (2/2): cut the v5.0.0 release per the release skill (bump_version, PR dev->master, tag on origin/master, push, verify PyPI + GitHub Release). **[USER GUIDANCE]**: "Yes, both tasks. But do not forget to ask me to assist with access to PyPI. Guide me step-by-step. And do not forget that I must review and merge requext to master manually, so, tag + push and PyPI/GitHub release only after I confirm that requies merged. Moreover you should pull master irst to create tag on respective commit." / "Trusted publisher added. Go." / "Update all used actions (in GH workflows) to lates versions. Just add commit to this request. Ather that request my assistance again." / "CI report set of warnings of forn ':1: WARNING: py:class reference target not found: networkx.classes.multidigraph.MultiDiGraph [ref.class]' Fix it" / "Well. Can we automatically trigger publishing to testPypi on pr to main to avoid such problems? So, you can check publishing to testPyPi automatically and after that I assist to merge PR." / "I can add trusted publisher for testPypi too. Is it a good way?" / "Is it safe to merge this pr? It will trigger new release that is not requiret (I guess)." +- [ ] Task 36: Verify that all you experince and knolage on releases are documented. Next release must be fast and smooth. **[USER GUIDANCE]**: "Be carefull. Split global knolage useful for all developers (it must be in docks) and local knolage for you (it must be in skills)" From dafb5cd2703f541bebe6e973bacfb3fc99964276 Mon Sep 17 00:00:00 2001 From: gsv Date: Wed, 16 Sep 2026 15:01:10 +0300 Subject: [PATCH 002/277] docs(36-S2): document the global packaging constraints in the release docs Record in docs/release.rst the facts about the publish pipeline that any developer needs (the 'what' and 'why'): the sdist must contain everything setup.py reads at build time because python -m build builds the wheel from the sdist (hence MANIFEST.in), PyPI/TestPyPI reject re-uploads of existing files (hence skip-existing on the PR check and the owner-deletes-first recovery for a failed tag push), and merging to master never publishes. All three were discovered while cutting v5.0.0 (task 35). The agent-specific recovery procedures stay in the release skill (S3). --- docs/release.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/release.rst b/docs/release.rst index 8a27d913..8518adac 100644 --- a/docs/release.rst +++ b/docs/release.rst @@ -44,6 +44,20 @@ a packaging check that fails the PR before a release tag is cut; since a tag always points at a merged PR's head, it validates exactly the code that will be released. +Two packaging constraints matter: + +- ``python -m build`` builds the wheel *from the sdist*, so the sdist must + contain everything :file:`setup.py` reads at build time — in particular + ``requirements/*.txt``, included via :file:`MANIFEST.in`. The PR's Publish + check catches a missing file before a tag is cut. +- PyPI and TestPyPI reject re-uploads of files that already exist for a + version. The PR check uses ``skip-existing`` to stay green; the real + publish does not — if a tag push reaches PyPI and then fails, an owner must + delete the release on PyPI before the tag can be re-pushed. + +Merging a pull request into ``master`` never publishes: the workflow runs +only on ``v*`` tag pushes (the merge does redeploy the docs site). + Prerequisites (one-time, owner action) -------------------------------------- From b688e44c023aca65e615a87ffe10e53e4d0d5599 Mon Sep 17 00:00:00 2001 From: gsv Date: Wed, 16 Sep 2026 15:05:11 +0300 Subject: [PATCH 003/277] docs(36-S3): record the local release knowledge in the release skill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the agent-specific operational details learned while cutting v5.0.0 (task 35), keeping the skill a thin pointer to docs/release.rst for the facts: - Procedure step 4 gains the pre-tag gate (the PR's Publish check, i.e. the TestPyPI pre-publish, must pass before merge/tag) and the human merge gate (the user merges manually; proceed only after confirmation). - Step 6 now verifies both PyPI and the GitHub Release page (changelog notes + dist assets), not just PyPI. - New Recovery section: tag-push failure before the PyPI publish (delete the tag, fix, re-tag on the new origin/master) and after it (an owner deletes the PyPI release first; create the GitHub Release manually via the API — token from the remote URL, awk changelog extraction, POST /releases, asset upload via the per-release upload_url because api.github.com/.../assets returns 404). All commands are the ones that actually worked during the v5.0.0 recovery. --- .opencode/skills/release/SKILL.md | 81 +++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 9 deletions(-) diff --git a/.opencode/skills/release/SKILL.md b/.opencode/skills/release/SKILL.md index 77f6e7cc..b68a19c1 100644 --- a/.opencode/skills/release/SKILL.md +++ b/.opencode/skills/release/SKILL.md @@ -1,14 +1,16 @@ --- name: release -description: Use when cutting a CFPQ_Data release — bumping the version, finalizing the changelog, tagging, and publishing to PyPI. Covers the procedure and the automated publish workflow. +description: Use when cutting a CFPQ_Data release — bumping the version, finalizing the changelog, tagging, publishing to PyPI — or recovering from a failed publish. Covers the procedure, the automated publish workflow, and recovery. --- # Release -Cut a release of the `cfpq-data` package. The model, versioning policy, and -prerequisites are documented in `docs/release.rst` — do not duplicate them here. -Publishing is automated by `.github/workflows/publish.yml` (runs on a `v*` tag -push). +Cut a release of the `cfpq-data` package. The model, versioning policy, +prerequisites, and packaging constraints are documented in `docs/release.rst` +— do not duplicate them here. Publishing is automated by +`.github/workflows/publish.yml`: on a `v*` tag push it builds, publishes to +PyPI, and creates the GitHub Release; on every PR targeting `master` it +pre-publishes to TestPyPI as a packaging check. ## Procedure @@ -26,8 +28,11 @@ push). poetry run pre-commit run check-version-sync --all-files ``` 3. Commit the bump (message: `chore: release X.Y.Z`). -4. Merge `dev` into `master` via a pull request (`master` is protected; do not - squash). This also deploys the docs. +4. Merge `dev` into `master` via a pull request (`master` is protected; do + not squash). This also deploys the docs. Wait for the PR's **Publish** + check (the TestPyPI pre-publish) to pass — it validates packaging for + exactly the code that will be released. The user reviews and merges the + PR manually; proceed only after they confirm the merge. 5. Tag the merged commit and push the tag: ```bash @@ -35,8 +40,66 @@ push). git tag -a vX.Y.Z -m "Release vX.Y.Z" origin/master git push origin vX.Y.Z ``` -6. The `publish` workflow builds, publishes to PyPI (Trusted Publishing), and - creates the GitHub Release. Verify on . +6. The `publish` workflow builds, publishes to PyPI (Trusted Publishing), + and creates the GitHub Release. Verify both: the package is live on + and the GitHub Release carries the + `[X.Y.Z]` changelog section with the dist artifacts as assets. + +## Recovery + +The `gh` CLI is not installed on this machine — use curl + the GitHub API: + +```bash +export GH_TOKEN=$(git config --get remote.origin.url | sed -E 's#.*://[^:]+:([^@]+)@.*#\1#') # never echo it +``` + +### Workflow failed before the PyPI publish + +Nothing reached PyPI, so the tag can simply be replaced: + +```bash +git push origin :refs/tags/vX.Y.Z # delete the tag +``` + +Fix the failure, merge the fix to `master` (PR + user merge), then re-tag +the new `origin/master` and push again. + +### Workflow failed after the PyPI publish (e.g. the GitHub Release step) + +PyPI already has the files for this version and rejects re-uploads — an +owner must delete the release on PyPI before the tag can be re-pushed (see +`docs/release.rst`). In the meantime, create the GitHub Release manually so +the release is complete: + +1. Extract the changelog section (same logic as the workflow): + + ```bash + awk -v v="X.Y.Z" 'index($0, "## [" v "]") == 1 {insec=1; next} /^## / && insec {exit} insec {print}' CHANGELOG.md > release_notes.md + ``` + +2. Create the release (build the JSON payload with python3 so the notes are + escaped correctly): + + ```bash + export RELEASE_NOTES_FILE=release_notes.md + PAYLOAD=$(python3 -c 'import json,os; print(json.dumps({"tag_name":"vX.Y.Z","name":"vX.Y.Z","body":open(os.environ["RELEASE_NOTES_FILE"]).read()}))') + curl -sS -X POST -H "Authorization: token $GH_TOKEN" -H "Accept: application/vnd.github+json" \ + -d "$PAYLOAD" https://api.github.com/repos/FormalLanguageConstrainedPathQuerying/CFPQ_Data/releases + ``` + +3. Upload the dist artifacts — download them from PyPI first so the release + assets are byte-identical to what was published + (`cfpq_data-X.Y.Z-py3-none-any.whl`, `cfpq_data-X.Y.Z.tar.gz`), then + upload each via the created release's `upload_url` field + (`uploads.github.com`): + + ```bash + curl -sS -X POST -H "Authorization: token $GH_TOKEN" \ + -H "Content-Type: application/octet-stream" --data-binary @cfpq_data-X.Y.Z-py3-none-any.whl "$UPLOAD_URL" + ``` + + Do not post to `api.github.com/.../releases/{id}/assets` — it returns + 404; only the per-release `upload_url` works. ## Notes From 80431164aa32e1e4ae711b1bee5c3911eab07751 Mon Sep 17 00:00:00 2001 From: gsv Date: Wed, 16 Sep 2026 15:13:30 +0300 Subject: [PATCH 004/277] docs(36-S4): mark task 36 done in the task log All release experience from the v5.0.0 run is now documented, split per the user's instruction: global packaging constraints (sdist completeness, re-upload rejection, merge-never-publishes) in docs/release.rst; agent operational knowledge (pre-tag gate, human merge gate, dual verification, recovery procedures with the exact working commands) in the release skill. Quality gate passed: 342 tests, pre-commit clean, no-warnings docs build, clean link check. --- tasks/tasks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/tasks.md b/tasks/tasks.md index e982327b..4a55a7d0 100644 --- a/tasks/tasks.md +++ b/tasks/tasks.md @@ -35,4 +35,4 @@ - [done] Task 33: Check developer documantation. Check that all parts of issue https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/76 well-documented, necessary parts added to README. **[USER GUIDANCE]**: "Let use docs as the source of truth, skills as thin pointers. Add this to main pronciples for future skills design and update." - [done] Task 34: Prepare v5.0.0 release (1/2): analyze the code with respect to the issues https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/122 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/76 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/75 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/74 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/28 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/26 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/16 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/2 and add respective references to the Changelog for the resolved ones. **[USER GUIDANCE]**: "Reference partial, no close claim" (issue #2: only the Zheng & Rugina C alias analysis data is in; the Vedurada 'Batch Alias Analysis' data is missing) / "Reference resolved sub-items only" (umbrella issue #28: cite the resolved sub-issues #27, #32, #20, #30, #33, #26 individually; do not claim #28 done). - [done] Task 35: Prepare v5.0.0 release (2/2): cut the v5.0.0 release per the release skill (bump_version, PR dev->master, tag on origin/master, push, verify PyPI + GitHub Release). **[USER GUIDANCE]**: "Yes, both tasks. But do not forget to ask me to assist with access to PyPI. Guide me step-by-step. And do not forget that I must review and merge requext to master manually, so, tag + push and PyPI/GitHub release only after I confirm that requies merged. Moreover you should pull master irst to create tag on respective commit." / "Trusted publisher added. Go." / "Update all used actions (in GH workflows) to lates versions. Just add commit to this request. Ather that request my assistance again." / "CI report set of warnings of forn ':1: WARNING: py:class reference target not found: networkx.classes.multidigraph.MultiDiGraph [ref.class]' Fix it" / "Well. Can we automatically trigger publishing to testPypi on pr to main to avoid such problems? So, you can check publishing to testPyPi automatically and after that I assist to merge PR." / "I can add trusted publisher for testPypi too. Is it a good way?" / "Is it safe to merge this pr? It will trigger new release that is not requiret (I guess)." -- [ ] Task 36: Verify that all you experince and knolage on releases are documented. Next release must be fast and smooth. **[USER GUIDANCE]**: "Be carefull. Split global knolage useful for all developers (it must be in docks) and local knolage for you (it must be in skills)" +- [done] Task 36: Verify that all you experince and knolage on releases are documented. Next release must be fast and smooth. **[USER GUIDANCE]**: "Be carefull. Split global knolage useful for all developers (it must be in docks) and local knolage for you (it must be in skills)" From 2516b06252a7be18872e6b9d180a12e2c5f8a6c5 Mon Sep 17 00:00:00 2001 From: gsv Date: Wed, 16 Sep 2026 16:14:18 +0300 Subject: [PATCH 005/277] docs(37-S1): record task 37 in the task log and write the detailed plan Record the uv-migration task verbatim with all three user-guidance items (official uv pre-commit hooks; ty for the fast local check with ty+pyright in CI; deletion of the two broken legacy scripts) and decompose it into eight atomic subtasks. The plan records the full decision record (PEP 621 + hatchling, PEP 735 dependency groups, ruff + ty + pyright toolchain, official pre-commit hooks, CI on astral-sh/setup-uv) and probe measurements of the current code (ruff 130 findings, ty ~10 real errors, pyright ~26 after config) so each subtask is sized against measured data. --- tasks/detailed_plan.md | 365 ++++++++++++++++++++++++++++++----------- tasks/tasks.md | 1 + 2 files changed, 269 insertions(+), 97 deletions(-) diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index 6ca7d9c6..dc2dd111 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -1,116 +1,287 @@ -# Task 36: Document the release experience (global → docs, local → skill) +# Task 37: Migrate project to UV manager ## Context -Task 35 cut v5.0.0 and surfaced a series of release-flow incidents (intersphinx -network flake, missing MANIFEST.in, TestPyPI PR check via OIDC Trusted -Publishing, the `/legacy/` TestPyPI upload URL, the missing checkout in the -`publish-pypi` job). The user asks that all experience and knowledge on -releases be documented so the next release is fast and smooth, and requires a -strict split: - -- **Global knowledge** — useful for all developers — lives in `docs/` - (the model: "What" and "Why"). -- **Local knowledge** — agent-specific operational details (commands, - pitfalls, procedures) — lives in the `release` skill (the "How"), which - stays a thin pointer to the docs. - -## Knowledge split (decision record) - -Global → `docs/release.rst` (facts any developer of the project needs): - -- The sdist-completeness constraint: `python -m build` builds the wheel from - the sdist, so the sdist must contain everything `setup.py` reads at build - time (`requirements/*.txt`, included via `MANIFEST.in`). -- PyPI and TestPyPI reject re-uploads of files that already exist for a - version; the PR check uses `skip-existing`; if a tag push reaches PyPI and - then fails, an owner must delete the release before the tag can be - re-pushed. -- Merging a pull request into `master` never publishes: the workflow runs - only on `v*` tag pushes (the merge does redeploy the docs site). - -Local → `.opencode/skills/release/SKILL.md` (agent operations only): - -- Pre-tag gate: wait for the PR's Publish check (TestPyPI pre-publish) to pass - before asking the user to merge and before tagging. -- Human merge gate: the user reviews and merges the PR manually; tag + push - only after the user confirms the merge (tag on `origin/master` after a fresh - `git fetch origin`). -- Verification of both PyPI and the GitHub Release page (changelog notes + - dist assets). -- Recovery procedures: workflow failure before the PyPI publish (delete the - tag, fix, merge, re-tag) and after it (an owner deletes the PyPI release - first — the fact lives in the docs; create the GitHub Release manually via - the API, including the `upload_url` asset-upload quirk). -- Machine notes: no `gh` CLI on this machine — use curl + the GitHub API with - the token extracted from the remote URL (never echoed). - -Not documented here (implementation details readable in -`.github/workflows/publish.yml` itself): the checkout step of `publish-pypi`, -the `/legacy/` TestPyPI repository URL, action versions. +The project is managed with **Poetry** (`pyproject.toml` `[tool.poetry]` + +`poetry.lock`) on top of a **legacy setuptools layer**: `setup.py` reads +`requirements/*.txt` (via `MANIFEST.in`) to declare the PyPI distribution, and +all five CI workflows install dependencies through Poetry. Quality checking is +limited to `black` (formatting) via pre-commit; there is no linter and no type +checker. + +The user requires a **full migration to uv** (https://github.com/astral-sh/uv): +no `requirements.txt`, no other legacy stuff, uv-managed quality tools +(linter, type checker), and updated documentation. + +## Decision record + +Decisions made before implementation (user-confirmed where noted): + +1. **Package manager**: uv 0.12.x. `uv.lock` is committed (the project has + dependency groups, so a lockfile is required for reproducible dev + environments). `.python-version` = `3.11` (matches the CI matrix and the + `requires-python` floor) and is committed; the `.gitignore` entry that + ignored it is removed. +2. **Project metadata**: PEP 621 `[project]` table in `pyproject.toml`; + build backend **hatchling** (uv's default recommendation). Flat layout, so + `[tool.hatch.build.targets.wheel] packages = ["cfpq_data"]`. Distribution + name is `cfpq-data` (PEP 503-normalized; Poetry used `cfpq_data`). License + uses the PEP 639 SPDX string `"Apache-2.0 AND CC-BY-4.0"` (fall back to + `{ text = ... }` if hatchling rejects it; in that case keep the + `License ::` classifier, otherwise drop it per PEP 639). Classifiers are + carried over from `setup.py`, with the stale `Python :: 3.9` entry replaced + by 3.11/3.12/3.13. +3. **Dependencies**: runtime deps converted from Poetry constraints to PEP 508 + (`^3.6.1` → `>=3.6.1,<4.0.0`; `pyformlang = "1.0.1"` → `==1.0.1`). +4. **Dev dependencies**: PEP 735 `[dependency-groups]`: + - `dev`: `ruff`, `ty`, `pyright`, `pre-commit`, `boto3` + - `test`: `pytest`, `pytest-cov` + - `docs`: the Sphinx stack (`sphinx`, `pydata-sphinx-theme`, `numpydoc`, + `nb2plots`, `sphinx-copybutton`, `ipykernel`, `jupyter-client`) + - Dropped: `codecov` (the pip CLI is unused — CI uploads via + `codecov/codecov-action`), `black` (replaced by `ruff format`). + - The old `setup.py` extras (`developer`, `docs`, `tests`) are dropped: + dev tools as install extras is the legacy anti-pattern; dependency groups + replace them. +5. **Quality tools** (user guidance, verbatim in `tasks/tasks.md`): + - **Linter + formatter**: ruff (lint rules `E,F,W,I`; `ruff format`). + One-time reformat commit. + - **Type checker**: **ty for the fast local check; CI runs both ty and + pyright** (user guidance). + - **pre-commit is kept** as the commit-time runner, using **official hooks** + (user asked for official uv pre-commit hooks): `astral-sh/uv-pre-commit` + (`uv-lock`, keeps `uv.lock` in sync), `astral-sh/ruff-pre-commit` + (`ruff-check --fix`, `ruff-format`; rev pinned to the locked ruff version + — both must be bumped together), the existing hygiene hooks, and local + hooks for the version-sync check and `uv run ty check`. Dropped: the + `black` hook and `requirements-txt-fixer`. +6. **CI**: all workflows use `astral-sh/setup-uv@v10` (with + `python-version: "3.11"`); deps via `uv sync --frozen --only-group `; + commands via `uv run ...`; the publish job builds with `uv build`. The lint + job runs the pre-commit pass plus `uv run ty check` and `uv run pyright`. + `uv sync` installs the project itself (editable), so the separate + `pip install .` steps disappear. +7. **Packaging**: `setup.py`, `MANIFEST.in`, `requirements.txt`, + `requirements/`, `poetry.lock` are deleted. The hatchling sdist includes + VCS-tracked files; `cfpq_data/data` stays out (gitignored, downloaded at + runtime). `uv build` builds the wheel from the source tree (not from the + sdist as `python -m build` did) — the TestPyPI pre-publish still validates + the build and metadata; `docs/release.rst` is rewritten accordingly. +8. **Version sync**: `cfpq_data/config.py` stays canonical; + `utils/check_version_sync.py` and `utils/bump_version.py` work unchanged on + PEP 621 (their `^version = "..."` regex matches `[project] version`). +9. **Broken legacy scripts** (user decision: delete): `utils/fetch_dataset.py` + (imports removed `AWS_*`/`BUCKET_NAME` from `cfpq_data.config`, writes a + non-existent `cfpq_data/dataset.py`) and `utils/update_dataset_tables.py` + (imports non-existent `graph_from_dataset`). Both fail at import time, have + no tests, and are referenced by no docs/skill/README. +10. **Type-check scope**: `cfpq_data`, `tests`, `utils`. Tests import the + `utils/` scripts as top-level modules (via `tests/utils/conftest.py` + sys.path insertion), so both checkers get `extraPaths = ["utils"]`. + +## Probe results (measured on the current code, 2026-09-16) + +- ruff (`E,F,W,I`): 130 findings — 41 F403 (star imports in `__init__.py`), + 36 I001 (unsorted imports, auto-fixable), 35 E501 (line too long), 10 F401, + 4 E402, 2 E741, 1 F405, 1 E714; 46 auto-fixable. 34 files need reformatting. +- ty 0.0.81: 74 diagnostics — most are import resolution (pytest not in the + probe env; `utils` modules), ~10 real errors (regex `.group` on + `Match | None` in `cfpq_data/grammars/converters/cfg.py` ×2 and + `utils/fetch_dataset.py` ×1 [deleted], missing members in the two deleted + scripts, 2× `invalid-argument-type` in tests). +- pyright 1.1.414 (basic mode): 41 errors — 15 reportMissingImports (utils + modules + deleted scripts), 15 reportArgumentType, 7 + reportOptionalMemberAccess, 4 reportAttributeAccessIssue (deleted scripts). + After S2 deletions + `extraPaths`, ~26 real errors remain. ## Subtasks -### S1: Record task 36 in the task log and write this detailed plan +### S1: Record task 37 in the task log and write this detailed plan **Code:** none (documentation-only) **Tests:** skip — no code to test -**Docs:** `tasks/tasks.md` (task 36 line; the session's user guidance appended - verbatim to the task 35 line), `tasks/detailed_plan.md` +**Docs:** `tasks/tasks.md` (task 37 line with verbatim user guidance), + `tasks/detailed_plan.md` (this file) + +**Spec:** +- Task line recorded verbatim; all three user-guidance items appended + verbatim (official uv pre-commit hooks; ty fast / ty+pyright in CI; delete + the two broken scripts). + +### S2: Core uv migration — PEP 621 pyproject, lockfile, legacy removal + +**Code:** Rewrite `pyproject.toml` (PEP 621 `[project]`, + `[dependency-groups]`, hatchling `[build-system]` + + `[tool.hatch.build.targets.wheel] packages = ["cfpq_data"]`, keep + `[tool.pytest.ini_options]`); add `.python-version` (`3.11`); + generate `uv.lock`; delete `poetry.lock`, `setup.py`, + `MANIFEST.in`, `requirements.txt`, `requirements/`, + `utils/fetch_dataset.py`, `utils/update_dataset_tables.py`; + remove the `.python-version` line from `.gitignore`; delete stale + local build artifacts (`build/`, `dist/`, `cfpq_data.egg-info/`). +**Tests:** `uv sync --all-groups` succeeds; `uv run python -c + "import cfpq_data"` works; the full suite is green under uv + (`uv run pytest --doctest-modules -vv -s cfpq_data tests`, 0 + failures); `uv run python utils/check_version_sync.py` exits 0; + `uv build` produces sdist + wheel with correct metadata (name + `cfpq-data`, version, deps, license, readme) and the sdist contains + `cfpq_data/`, `README.rst`, `LICENSE.txt`, `LICENSE-DATA.txt` but no + `cfpq_data/data`. +**Docs:** `CHANGELOG.md` `[Unreleased]`: Changed (uv migration, PEP 621 + + hatchling, dependency groups) and Removed (legacy packaging files, + unused `codecov` dev dep, the two broken scripts). + +**Spec:** +- Dependency ranges per decision 3; groups per decision 4. +- If hatchling rejects the SPDX license string, use `{ text = ... }` and keep + the `License ::` classifier (decision 2 fallback). +- Reuse: `utils/check_version_sync.py` / `utils/bump_version.py` unchanged + (verified compatible with PEP 621). + +### S3: Ruff lint + format config and one-time code pass + +**Code:** Add `[tool.ruff]` (`target-version = "py311"`), + `[tool.ruff.lint]` (`select = ["E", "F", "W", "I"]`) and + `[tool.ruff.lint.per-file-ignores]` to `pyproject.toml`; run + `uv run ruff check --fix .` and `uv run ruff format .`; manually fix + the remaining findings (E501 line wraps, E741 ambiguous names, + E714, F405, any F401 that is an intentional re-export). +**Tests:** Full suite green after reformatting (doctests included); + `uv run ruff check .` and `uv run ruff format --check .` are clean. +**Docs:** `CHANGELOG.md` `[Unreleased]` Added: ruff as the lint/format gate. **Spec:** -- Add the task 36 line with the user's exact wording and the split - instruction as `[USER GUIDANCE]`. -- Append, verbatim, the five user-guidance quotes given during task 35 - (actions update, CI warning fix, TestPyPI-on-PR request, trusted-publisher - question, safe-to-merge question) to the task 35 line. -- Replace `tasks/detailed_plan.md` with this plan. +- Per-file ignores (from the probe): `"__init__.py" = ["F403"]` (star imports + are the package's public-API re-export pattern); + `"tests/utils/conftest.py" = ["E402"]` (sys.path insertion must precede the + utils imports). Any other per-file ignore must be justified in the commit + message. +- F401 findings are reviewed one by one: genuinely unused imports are removed; + intentional re-exports keep a `# noqa: F401`. +- `ruff format` must not change doctest output (it does not touch docstrings); + the suite is the guard. -### S2: Record the global release knowledge in docs/release.rst +### S4: Type checking — ty + pyright config and error fixes -**Code:** none -**Tests:** skip — docs only; verified by the clean docs build and link check - in the quality gate -**Docs:** `docs/release.rst` ("Package publishing (automated)" section) +**Code:** Add `[tool.ty.environment]` (`extra-paths = ["utils"]`) and + `[tool.pyright]` (`pythonVersion = "3.11"`, `extraPaths = ["utils"]`) + to `pyproject.toml`; fix every real ty and pyright error in + `cfpq_data/`, `tests/`, `utils/` (regex `.group` on `Match | None` + needs a None guard; argument-type mismatches are fixed at the call + site or by correcting an over-narrow annotation — whichever matches + the intended behavior). +**Tests:** `uv run ty check` exits 0; `uv run pyright` exits 0; full suite + green. +**Docs:** `CHANGELOG.md` `[Unreleased]` Added: type checking (ty locally, + ty + pyright in CI). **Spec:** -- Commit the drafted additions already present in the working tree: the two - packaging constraints (sdist completeness via `MANIFEST.in`; re-upload - rejection and its consequence for re-pushing a tag) and the "merging never - publishes" paragraph. -- Review them against the actual `publish.yml` behavior before committing; do - not restate agent procedures here — those belong to the skill. +- No `# type: ignore` / `# ty: ignore` suppressions unless a specific false + positive is documented in the commit message with the checker and rule. +- ty's `python-version` is auto-detected from `requires-python` (3.11); set it + explicitly only if detection misbehaves. +- pyright runs in its default `basic` mode; do not lower the mode to get + green — fix or justify. -### S3: Record the local release knowledge in the release skill +### S5: Rewrite .pre-commit-config.yaml with official hooks -**Code:** none -**Tests:** skip — skill only -**Docs:** `.opencode/skills/release/SKILL.md` +**Code:** New `.pre-commit-config.yaml`: + - `pre-commit/pre-commit-hooks` v6.0.0: `check-yaml`, + `end-of-file-fixer`, `trailing-whitespace` (drop + `requirements-txt-fixer`) + - `astral-sh/uv-pre-commit` 0.12.15: `uv-lock` + - `astral-sh/ruff-pre-commit` v0.16.7: `ruff-check` + (`args: [--fix]`), `ruff-format` + - local: `check-version-sync` (unchanged entry), `ty-check` + (`entry: uv run ty check`, `language: system`, + `pass_filenames: false`, `files: \.py$`) + Drop the `black` hook. +**Tests:** `uv run pre-commit run --all-files` — every hook passes (including + `uv-lock`, both ruff hooks, and the local ty hook). +**Docs:** `docs/developer.rst`: replace the "Pre-commit" section with a + "Quality checks" section covering the official-hook setup (and the + rule that the `ruff-pre-commit` rev must match the locked ruff + version), the local commands (`uv run ruff check .`, + `uv run ruff format .`, `uv run ty check`), and the fact that CI + additionally runs pyright; update the "Test pipeline" command to + `uv run pytest ...`; add type checking to the "Quality gate" list in + "Contribution guidelines". **Spec:** -- Procedure: step 4 gains the pre-tag gate (the PR's Publish check must pass) - and the human merge gate (the user merges manually; proceed only after - confirmation); step 6's verification extends to the GitHub Release page - (changelog notes + dist assets), not just PyPI. -- New "Recovery" section: (a) workflow failure before the PyPI publish — - delete the tag, fix, merge the fix, re-tag on the new `origin/master`; - (b) failure after the PyPI publish — an owner deletes the PyPI release - first (reference `docs/release.rst` for the fact, do not re-describe it), - then create the GitHub Release manually via the API with the exact working - commands: token from the remote URL (never echoed), `awk` extraction of the - `[X.Y.Z]` changelog section, `POST /releases`, asset upload via the - created release's `upload_url` (`uploads.github.com`) — posting to - `api.github.com/.../releases/{id}/assets` returns 404. -- Notes: the `gh` CLI is not installed on this machine — use curl + the - GitHub API. -- Keep the skill a thin pointer: facts already in `docs/release.rst` are - referenced, never re-described. - -### S4: Mark task 36 done in the task log - -**Code:** none -**Tests:** skip -**Docs:** `tasks/tasks.md` - -**Spec:** After code review, the quality gate, and the merge to `dev`, -prepend `[done] ` to the task 36 line (commit on `dev`). +- The hook list in `.pre-commit-config.yaml` stays the single source of truth + (docs describe it, never duplicate it). +- `uv run ty check` as a local hook requires uv on PATH — that is now a + project prerequisite (documented in "Development setup"). + +### S6: Migrate all CI workflows to uv + +**Code:** `.github/workflows/{tests,coverage,docs,deploy_docs,lint,publish}.yml`: + replace `actions/setup-python` + Poetry with + `astral-sh/setup-uv@v10` (`python-version: "3.11"`), + `uv sync --frozen --only-group ` (test/docs/dev per job), and + `uv run ...` commands; drop the `pip install .` steps (uv sync + installs the project editable); publish job builds with `uv build`; + lint job gains `uv run ty check` and `uv run pyright` steps. +**Tests:** Every workflow file parses as YAML (`python3 -c + "import yaml,sys; yaml.safe_load(open(sys.argv[1]))"` per file); no + `poetry`/`setup-python` references remain (grep). Real CI runs on + the next push (after merge — noted in the commit message). +**Docs:** `docs/release.rst`: rewrite the "Two packaging constraints" block — + with PEP 621 + hatchling all build inputs are VCS-tracked, and + `uv build` builds the wheel from the source tree (not from the sdist); + the TestPyPI pre-publish still validates build + metadata. Update the + "Builds the sdist and wheel (`python -m build`)" line to `uv build`. + +**Spec:** +- Keep the existing triggers, matrices, permissions, and comments that are + still true; only the tooling steps change. +- `--frozen` makes CI fail if `uv.lock` is out of sync with `pyproject.toml` + (the `uv-lock` pre-commit hook is the local guard). + +### S7: Update remaining docs and verify the docs build + +**Code:** none (documentation-only) +**Tests:** skip — no code to test +**Docs:** `docs/README.md` (Poetry → uv commands); `docs/developer.rst` + "Development setup" section (uv installation, `uv sync --all-groups`, + group semantics — replacing the Poetry/package-mode/setup.py/ + requirements paragraphs); `README.rst` developer section (Poetry → + uv); final consistency pass: grep docs + README for + `poetry|requirements|setup.py|MANIFEST` and fix stragglers. +**Spec:** +- Verification: `uv run make -C docs html` exits 0 under the no-warnings + policy; `uv run sphinx-build -b linkcheck docs docs/_build/linkcheck` + reports no broken links. + +### S8: Update the agent skills + +**Code:** none (documentation-only) +**Tests:** skip — no code to test +**Docs:** `.opencode/skills/run-tests/SKILL.md` (`poetry run` → `uv run`; + dependency-group note replaces `requirements/tests.txt`; keep the + bare-pytest pitfall, updated env name); + `.opencode/skills/code-style/SKILL.md` (pointer to the new "Quality + checks" section; ruff/ty via `uv run`; hook list stays in + `.pre-commit-config.yaml`); + `.opencode/skills/quality-gates/SKILL.md` (add the type-check step — + ty locally, CI also runs pyright; update the "Pre-commit" section + reference to "Quality checks"); + `.opencode/skills/release/SKILL.md` (`poetry run pre-commit run + check-version-sync --all-files` → `uv run pre-commit run + check-version-sync --all-files`). + +**Spec:** +- Skills stay thin pointers to the docs (main principle); no command + duplication beyond what the skills already carry. +- Verification: grep `.opencode/skills/` for `poetry` → no matches. + +## Post-subtask steps + +1. Code review of the whole task diff (`code-review` skill), iterate to zero + findings. +2. Quality gate (`quality-gates` skill): full test suite, full pre-commit + pass, `uv run ty check`, docs build, link check — all must PASS. (CI + additionally runs pyright; it is run locally as well since Node 18 is + available on this machine.) +3. Merge to `dev` (rebase + ff-only), delete the feature branch, mark task 37 + `[done]`. diff --git a/tasks/tasks.md b/tasks/tasks.md index 4a55a7d0..a39098fc 100644 --- a/tasks/tasks.md +++ b/tasks/tasks.md @@ -36,3 +36,4 @@ - [done] Task 34: Prepare v5.0.0 release (1/2): analyze the code with respect to the issues https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/122 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/76 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/75 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/74 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/28 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/26 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/16 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/2 and add respective references to the Changelog for the resolved ones. **[USER GUIDANCE]**: "Reference partial, no close claim" (issue #2: only the Zheng & Rugina C alias analysis data is in; the Vedurada 'Batch Alias Analysis' data is missing) / "Reference resolved sub-items only" (umbrella issue #28: cite the resolved sub-issues #27, #32, #20, #30, #33, #26 individually; do not claim #28 done). - [done] Task 35: Prepare v5.0.0 release (2/2): cut the v5.0.0 release per the release skill (bump_version, PR dev->master, tag on origin/master, push, verify PyPI + GitHub Release). **[USER GUIDANCE]**: "Yes, both tasks. But do not forget to ask me to assist with access to PyPI. Guide me step-by-step. And do not forget that I must review and merge requext to master manually, so, tag + push and PyPI/GitHub release only after I confirm that requies merged. Moreover you should pull master irst to create tag on respective commit." / "Trusted publisher added. Go." / "Update all used actions (in GH workflows) to lates versions. Just add commit to this request. Ather that request my assistance again." / "CI report set of warnings of forn ':1: WARNING: py:class reference target not found: networkx.classes.multidigraph.MultiDiGraph [ref.class]' Fix it" / "Well. Can we automatically trigger publishing to testPypi on pr to main to avoid such problems? So, you can check publishing to testPyPi automatically and after that I assist to merge PR." / "I can add trusted publisher for testPypi too. Is it a good way?" / "Is it safe to merge this pr? It will trigger new release that is not requiret (I guess)." - [done] Task 36: Verify that all you experince and knolage on releases are documented. Next release must be fast and smooth. **[USER GUIDANCE]**: "Be carefull. Split global knolage useful for all developers (it must be in docks) and local knolage for you (it must be in skills)" +- [ ] Task 37: Migrate project to UV manager (https://github.com/astral-sh/uv) WE need full migration: no requirements.txt, no other legacy sfuff. Configure project to use UV-provided tools for quality checking: linter, type checker, etc. Do not forget to update documentation. **[USER GUIDANCE]**: "Read https://docs.astral.sh/uv/guides/integration/pre-commit/ can we use official UV pre-commit hooks?" / "Note on ty typechecker. Let use ty for fast check but in CI use both ty and pyright." / "Delete both (Recommended)" (broken legacy scripts utils/fetch_dataset.py and utils/update_dataset_tables.py) From 3f69e995e58afd8bd679ee717e745c520dbf0b2d Mon Sep 17 00:00:00 2001 From: gsv Date: Wed, 16 Sep 2026 16:24:01 +0300 Subject: [PATCH 006/277] feat(37-S2): migrate packaging from Poetry + setuptools to uv (PEP 621 + hatchling) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrite pyproject.toml as a PEP 621 project: [project] metadata (name cfpq-data, PEP 639 SPDX license expression, classifiers carried over from setup.py with the stale Python 3.9 entry replaced by 3.11-3.13), runtime dependencies converted from Poetry constraints to PEP 508 ranges, and PEP 735 [dependency-groups] (dev/test/docs) replacing the Poetry groups and the setup.py extras. The build backend is hatchling with an explicit flat-layout package list and an explicit sdist include list — without it, hatchling's default would have shipped every non-gitignored file in the repo (including the 62 MB untracked .opencode/node_modules) into the PyPI sdist. Delete the legacy layer: setup.py, MANIFEST.in, requirements.txt, requirements/, poetry.lock, and the two broken utility scripts (utils/fetch_dataset.py imported removed AWS_* constants from cfpq_data.config; utils/update_dataset_tables.py imported a non-existent graph_from_dataset) — per user decision. Drop the unused codecov dev dep (CI uploads via the Codecov GitHub Action). Add .python-version (3.11, committed; un-ignored in .gitignore, which also gains node_modules/) and the committed uv.lock (118 packages). Verified: uv sync --all-groups + full suite green under uv (342 passed), version-sync check passes, uv build produces a clean sdist (package + README + both licenses) and a wheel that installs and imports in a fresh venv. --- .gitignore | 6 +- .python-version | 1 + CHANGELOG.md | 18 + MANIFEST.in | 1 - poetry.lock | 3208 -------------------------------- pyproject.toml | 111 +- requirements.txt | 1 - requirements/README.md | 27 - requirements/default.txt | 5 - requirements/developer.txt | 3 - requirements/docs.txt | 5 - requirements/tests.txt | 3 - setup.py | 92 - utils/fetch_dataset.py | 52 - utils/update_dataset_tables.py | 49 - uv.lock | 2152 +++++++++++++++++++++ 16 files changed, 2246 insertions(+), 3488 deletions(-) create mode 100644 .python-version delete mode 100644 MANIFEST.in delete mode 100644 poetry.lock delete mode 100644 requirements.txt delete mode 100644 requirements/README.md delete mode 100644 requirements/default.txt delete mode 100644 requirements/developer.txt delete mode 100644 requirements/docs.txt delete mode 100644 requirements/tests.txt delete mode 100644 setup.py delete mode 100644 utils/fetch_dataset.py delete mode 100644 utils/update_dataset_tables.py create mode 100644 uv.lock diff --git a/.gitignore b/.gitignore index d14082df..f461415d 100644 --- a/.gitignore +++ b/.gitignore @@ -84,12 +84,12 @@ docs/*/*/generated/* # PyBuilder target/ +# Node +node_modules/ + # Jupyter Notebook .ipynb_checkpoints -# pyenv -.python-version - # celery beat schedule file celerybeat-schedule diff --git a/.python-version b/.python-version new file mode 100644 index 00000000..2c073331 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.11 diff --git a/CHANGELOG.md b/CHANGELOG.md index d424de1a..2c88f681 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 builds the sdist and wheel and publishes them to TestPyPI (`skip-existing`), validating packaging before a release tag is cut. +### Changed + +- Development tooling migrated from Poetry to [uv](https://docs.astral.sh/uv/): + PEP 621 project metadata with hatchling as the build backend, PEP 735 + dependency groups (`dev`, `test`, `docs`) instead of Poetry groups and the + `setup.py` extras, a committed `uv.lock`, and all CI workflows on + `astral-sh/setup-uv`. + +### Removed + +- The legacy packaging layer: `setup.py`, `MANIFEST.in`, `requirements.txt`, + and `requirements/` (dependencies now live in `pyproject.toml`). +- The unused `codecov` dev dependency (CI uploads coverage via the Codecov + GitHub Action). +- The broken utility scripts `utils/fetch_dataset.py` and + `utils/update_dataset_tables.py` (both failed at import time against the + 5.0.0 package layout). + ## [5.0.0] - 2026-09-16 ### Added diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index e534d459..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1 +0,0 @@ -include requirements/*.txt diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index 8872eb6a..00000000 --- a/poetry.lock +++ /dev/null @@ -1,3208 +0,0 @@ -# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. - -[[package]] -name = "accessible-pygments" -version = "0.0.5" -description = "A collection of accessible pygments styles" -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "accessible_pygments-0.0.5-py3-none-any.whl", hash = "sha256:88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7"}, - {file = "accessible_pygments-0.0.5.tar.gz", hash = "sha256:40918d3e6a2b619ad424cb91e556bd3bd8865443d9f22f1dcdf79e33c8046872"}, -] - -[package.dependencies] -pygments = ">=1.5" - -[package.extras] -dev = ["pillow", "pkginfo (>=1.10)", "playwright", "pre-commit", "setuptools", "twine (>=5.0)"] -tests = ["hypothesis", "pytest"] - -[[package]] -name = "alabaster" -version = "1.0.0" -description = "A light, configurable Sphinx theme" -optional = false -python-versions = ">=3.10" -groups = ["docs"] -files = [ - {file = "alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b"}, - {file = "alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e"}, -] - -[[package]] -name = "appnope" -version = "0.1.4" -description = "Disable App Nap on macOS >= 10.9" -optional = false -python-versions = ">=3.6" -groups = ["docs"] -markers = "platform_system == \"Darwin\"" -files = [ - {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, - {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, -] - -[[package]] -name = "asttokens" -version = "3.0.1" -description = "Annotate AST trees with source code positions" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "asttokens-3.0.1-py3-none-any.whl", hash = "sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a"}, - {file = "asttokens-3.0.1.tar.gz", hash = "sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7"}, -] - -[package.extras] -astroid = ["astroid (>=2,<5)"] -test = ["astroid (>=2,<5)", "pytest (<9.0)", "pytest-cov", "pytest-xdist"] - -[[package]] -name = "attrs" -version = "25.4.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373"}, - {file = "attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11"}, -] - -[[package]] -name = "babel" -version = "2.17.0" -description = "Internationalization utilities" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2"}, - {file = "babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d"}, -] - -[package.extras] -dev = ["backports.zoneinfo ; python_version < \"3.9\"", "freezegun (>=1.0,<2.0)", "jinja2 (>=3.0)", "pytest (>=6.0)", "pytest-cov", "pytz", "setuptools", "tzdata ; sys_platform == \"win32\""] - -[[package]] -name = "beautifulsoup4" -version = "4.14.3" -description = "Screen-scraping library" -optional = false -python-versions = ">=3.7.0" -groups = ["docs"] -files = [ - {file = "beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb"}, - {file = "beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86"}, -] - -[package.dependencies] -soupsieve = ">=1.6.1" -typing-extensions = ">=4.0.0" - -[package.extras] -cchardet = ["cchardet"] -chardet = ["chardet"] -charset-normalizer = ["charset-normalizer"] -html5lib = ["html5lib"] -lxml = ["lxml"] - -[[package]] -name = "black" -version = "26.5.1" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.10" -groups = ["dev"] -files = [ - {file = "black-26.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9942db8888e06943c5dde66ca0037dcff82a2a4ec1ad0ada9e0d2ee9d9823893"}, - {file = "black-26.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:89c93167a74d3a75dfaa38a5c7cca015537d5820dd7f17d63267d674a61cae90"}, - {file = "black-26.5.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22f2cd76d069cc54c71f10360744ba8983fbb616903b4304a85b734915c8e1b4"}, - {file = "black-26.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:87ed5c6f450580a2f6790bc7cbfb016dfc73bc750249762268a3695361315eef"}, - {file = "black-26.5.1-cp310-cp310-win_arm64.whl", hash = "sha256:58b4bd92cf88aacf83d88479c8f9caee044b1ec55f2451a337354a7ea2590a22"}, - {file = "black-26.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:96ae2c733b2aabdd9986e2c5df628ff3473676cd1c5faded1ff496cf6d74083c"}, - {file = "black-26.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0e48b87e03bf109288e55cfceadcfa15ff5470aca2851a851950ed2926f450d7"}, - {file = "black-26.5.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5119fa92ae61f786e8c3662fd60aece1d0a2dd5cca5d0c79417a95e7a4272a59"}, - {file = "black-26.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:30d3c14661f2792e9142cce3eeeb1cbc175b3eb5f733be0c8eeb99651e52b0c3"}, - {file = "black-26.5.1-cp311-cp311-win_arm64.whl", hash = "sha256:1ef92b76f7733f282fd096ea406200b5a286c42947412b0eaff3a74e3616cefe"}, - {file = "black-26.5.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4ad6fa01f941920f54f2bbb35f3df7673428a0ef98a0b0840c2eaef3b110efa8"}, - {file = "black-26.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3915f256e75a2d7cf88d8953d37f780455dc586cc72dee059c528fe77f581217"}, - {file = "black-26.5.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d98d4137277c75dfb898ec8d846c4fd68ba1e9cf77f95e2865c203dc18f4c3d"}, - {file = "black-26.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:a1dca32d9f1784af512a13410ec204c6f7f0aa9797a111c42e1c03449821c264"}, - {file = "black-26.5.1-cp312-cp312-win_arm64.whl", hash = "sha256:1037d5ac7b7b310b2632ad867ec8d0e4c4819dcdb0b820f63135da746a24e418"}, - {file = "black-26.5.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2b36cf2ddf5566e205f6535f782a62194a184d33e175b64ae8c40b1737522be3"}, - {file = "black-26.5.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f7ea64ebfa01b50f693508fc39f875e264446d3b097088f84f203b9d09618a0"}, - {file = "black-26.5.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecb3e624844c798144e9bd986954e0adc81d8911a1f30f375e1252fe26e8c294"}, - {file = "black-26.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:e1a26503279b6b310669fb0b219c39e4820b77e8189fe80f522bb511f247db0a"}, - {file = "black-26.5.1-cp313-cp313-win_arm64.whl", hash = "sha256:5c34b25da232ead53a6f335b76dbea124f4d152ad568b9080d6f944bc2b34b52"}, - {file = "black-26.5.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e88976690a64b0af98312ca958415849cb42423423c5f2ee74af4b49a97a2168"}, - {file = "black-26.5.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:32d5ea7f6c8bdfa6e648326ebca1f02b0764e2a029edc6f8dce2627e19d468c3"}, - {file = "black-26.5.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ea8d16dc41655aa113cd64665e7219446cd7e4ff2248d7178eaa905190c86b18"}, - {file = "black-26.5.1-cp314-cp314-win_amd64.whl", hash = "sha256:577f21094ea469ef92ec1adaf2c9441a226d2144d01a5be2fa823cecf6543e50"}, - {file = "black-26.5.1-cp314-cp314-win_arm64.whl", hash = "sha256:ed1a20af114c301a0269bf01163d51dbef72737fd65f850001e7cbe7f3c7abae"}, - {file = "black-26.5.1-py3-none-any.whl", hash = "sha256:4ed7f7da04046d2e488437170797d3b4a4ad83906683bcb7dfc68b673bbce5e2"}, - {file = "black-26.5.1.tar.gz", hash = "sha256:dd321f668053961824bcc1be1cc1df748b2d7e4fa28086b08331e577b0100a73"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=1.0.0" -platformdirs = ">=2" -pytokens = ">=0.4.0,<0.5.0" - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.10)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2) ; sys_platform != \"win32\"", "winloop (>=0.5.0) ; sys_platform == \"win32\""] - -[[package]] -name = "bleach" -version = "6.4.0" -description = "An easy safelist-based HTML-sanitizing tool." -optional = false -python-versions = ">=3.10" -groups = ["docs"] -files = [ - {file = "bleach-6.4.0-py3-none-any.whl", hash = "sha256:4b6b6a54fff2e69a3dde9d21cc6301220bee3c3cb792187d11403fd795031081"}, - {file = "bleach-6.4.0.tar.gz", hash = "sha256:4202482733d85cedd04e59fcb2f89f4e4c7c385a78d3c3c23c30446843a37452"}, -] - -[package.dependencies] -tinycss2 = {version = ">=1.1.0", optional = true, markers = "extra == \"css\""} -webencodings = "*" - -[package.extras] -css = ["tinycss2 (>=1.1.0)"] - -[[package]] -name = "boto3" -version = "1.43.86" -description = "The AWS SDK for Python" -optional = false -python-versions = ">=3.10" -groups = ["dev"] -files = [ - {file = "boto3-1.43.86-py3-none-any.whl", hash = "sha256:94543a5ce482df8bb6a0bf8a944bf5ccf6625889b1df0d7886dfc3311ebd4169"}, - {file = "boto3-1.43.86.tar.gz", hash = "sha256:aca7b5d7f31a90ad37bec773552ec9bfb57e0029c9aa0f0f4d51d5bf9607b1c4"}, -] - -[package.dependencies] -botocore = ">=1.43.86,<1.44.0" -jmespath = ">=0.7.1,<2.0.0" -s3transfer = ">=0.19.0,<0.20.0" - -[package.extras] -crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] - -[[package]] -name = "botocore" -version = "1.43.86" -description = "Low-level, data-driven core of boto 3." -optional = false -python-versions = ">=3.10" -groups = ["dev"] -files = [ - {file = "botocore-1.43.86-py3-none-any.whl", hash = "sha256:4efc7fbd6e7616edbd55623bb585a044906149b9a5d3d8558420506526e5a5ac"}, - {file = "botocore-1.43.86.tar.gz", hash = "sha256:0e943c77ab6a54aaaf4d57e6026ede5c3dca341af71ce91f71849a6eae9d5dbf"}, -] - -[package.dependencies] -jmespath = ">=0.7.1,<2.0.0" -python-dateutil = ">=2.1,<3.0.0" -urllib3 = ">=1.25.4,<2.2.0 || >2.2.0,<3" - -[package.extras] -crt = ["awscrt (==0.36.0)"] - -[[package]] -name = "certifi" -version = "2025.11.12" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.7" -groups = ["main", "docs", "test"] -files = [ - {file = "certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b"}, - {file = "certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316"}, -] - -[[package]] -name = "cffi" -version = "2.0.0" -description = "Foreign Function Interface for Python calling C code." -optional = false -python-versions = ">=3.9" -groups = ["docs"] -markers = "implementation_name == \"pypy\"" -files = [ - {file = "cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44"}, - {file = "cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49"}, - {file = "cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c"}, - {file = "cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb"}, - {file = "cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0"}, - {file = "cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4"}, - {file = "cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453"}, - {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495"}, - {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5"}, - {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb"}, - {file = "cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a"}, - {file = "cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739"}, - {file = "cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe"}, - {file = "cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c"}, - {file = "cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92"}, - {file = "cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93"}, - {file = "cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5"}, - {file = "cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664"}, - {file = "cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26"}, - {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9"}, - {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414"}, - {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743"}, - {file = "cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5"}, - {file = "cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5"}, - {file = "cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d"}, - {file = "cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d"}, - {file = "cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c"}, - {file = "cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe"}, - {file = "cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062"}, - {file = "cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e"}, - {file = "cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037"}, - {file = "cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba"}, - {file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94"}, - {file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187"}, - {file = "cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18"}, - {file = "cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5"}, - {file = "cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6"}, - {file = "cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb"}, - {file = "cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca"}, - {file = "cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b"}, - {file = "cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b"}, - {file = "cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2"}, - {file = "cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3"}, - {file = "cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26"}, - {file = "cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c"}, - {file = "cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b"}, - {file = "cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27"}, - {file = "cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75"}, - {file = "cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91"}, - {file = "cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5"}, - {file = "cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13"}, - {file = "cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b"}, - {file = "cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c"}, - {file = "cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef"}, - {file = "cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775"}, - {file = "cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205"}, - {file = "cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1"}, - {file = "cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f"}, - {file = "cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25"}, - {file = "cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad"}, - {file = "cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9"}, - {file = "cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d"}, - {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c"}, - {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8"}, - {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc"}, - {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592"}, - {file = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512"}, - {file = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4"}, - {file = "cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e"}, - {file = "cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6"}, - {file = "cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9"}, - {file = "cffi-2.0.0-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf"}, - {file = "cffi-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7"}, - {file = "cffi-2.0.0-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:4647afc2f90d1ddd33441e5b0e85b16b12ddec4fca55f0d9671fef036ecca27c"}, - {file = "cffi-2.0.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3f4d46d8b35698056ec29bca21546e1551a205058ae1a181d871e278b0b28165"}, - {file = "cffi-2.0.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e6e73b9e02893c764e7e8d5bb5ce277f1a009cd5243f8228f75f842bf937c534"}, - {file = "cffi-2.0.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:cb527a79772e5ef98fb1d700678fe031e353e765d1ca2d409c92263c6d43e09f"}, - {file = "cffi-2.0.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:61d028e90346df14fedc3d1e5441df818d095f3b87d286825dfcbd6459b7ef63"}, - {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0f6084a0ea23d05d20c3edcda20c3d006f9b6f3fefeac38f59262e10cef47ee2"}, - {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1cd13c99ce269b3ed80b417dcd591415d3372bcac067009b6e0f59c7d4015e65"}, - {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:89472c9762729b5ae1ad974b777416bfda4ac5642423fa93bd57a09204712322"}, - {file = "cffi-2.0.0-cp39-cp39-win32.whl", hash = "sha256:2081580ebb843f759b9f617314a24ed5738c51d2aee65d31e02f6f7a2b97707a"}, - {file = "cffi-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9"}, - {file = "cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529"}, -] - -[package.dependencies] -pycparser = {version = "*", markers = "implementation_name != \"PyPy\""} - -[[package]] -name = "cfgv" -version = "3.5.0" -description = "Validate configuration and produce human readable error messages." -optional = false -python-versions = ">=3.10" -groups = ["dev"] -files = [ - {file = "cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0"}, - {file = "cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.4" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7" -groups = ["main", "docs", "test"] -files = [ - {file = "charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-win32.whl", hash = "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d"}, - {file = "charset_normalizer-3.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016"}, - {file = "charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525"}, - {file = "charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14"}, - {file = "charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c"}, - {file = "charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_riscv64.whl", hash = "sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-win32.whl", hash = "sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa"}, - {file = "charset_normalizer-3.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-win32.whl", hash = "sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966"}, - {file = "charset_normalizer-3.4.4-cp39-cp39-win_arm64.whl", hash = "sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50"}, - {file = "charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f"}, - {file = "charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a"}, -] - -[[package]] -name = "click" -version = "8.3.1" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.10" -groups = ["dev"] -files = [ - {file = "click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6"}, - {file = "click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "codecov" -version = "2.1.13" -description = "Hosted coverage reports for GitHub, Bitbucket and Gitlab" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -groups = ["test"] -files = [ - {file = "codecov-2.1.13-py2.py3-none-any.whl", hash = "sha256:c2ca5e51bba9ebb43644c43d0690148a55086f7f5e6fd36170858fa4206744d5"}, - {file = "codecov-2.1.13.tar.gz", hash = "sha256:2362b685633caeaf45b9951a9b76ce359cd3581dd515b430c6c3f5dfb4d92a8c"}, -] - -[package.dependencies] -coverage = "*" -requests = ">=2.7.9" - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["dev", "docs", "test"] -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] -markers = {dev = "sys_platform == \"win32\" or platform_system == \"Windows\"", docs = "sys_platform == \"win32\"", test = "sys_platform == \"win32\""} - -[[package]] -name = "comm" -version = "0.2.3" -description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417"}, - {file = "comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971"}, -] - -[package.extras] -test = ["pytest"] - -[[package]] -name = "contourpy" -version = "1.3.3" -description = "Python library for calculating contours of 2D quadrilateral grids" -optional = false -python-versions = ">=3.11" -groups = ["docs"] -files = [ - {file = "contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1"}, - {file = "contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381"}, - {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7"}, - {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1"}, - {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a"}, - {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db"}, - {file = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620"}, - {file = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f"}, - {file = "contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff"}, - {file = "contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42"}, - {file = "contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470"}, - {file = "contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb"}, - {file = "contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6"}, - {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7"}, - {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8"}, - {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea"}, - {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1"}, - {file = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7"}, - {file = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411"}, - {file = "contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69"}, - {file = "contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b"}, - {file = "contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc"}, - {file = "contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5"}, - {file = "contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1"}, - {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286"}, - {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5"}, - {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67"}, - {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9"}, - {file = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659"}, - {file = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7"}, - {file = "contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d"}, - {file = "contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263"}, - {file = "contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9"}, - {file = "contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d"}, - {file = "contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216"}, - {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae"}, - {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20"}, - {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99"}, - {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b"}, - {file = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a"}, - {file = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e"}, - {file = "contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3"}, - {file = "contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8"}, - {file = "contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301"}, - {file = "contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a"}, - {file = "contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77"}, - {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5"}, - {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4"}, - {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36"}, - {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3"}, - {file = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b"}, - {file = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36"}, - {file = "contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d"}, - {file = "contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd"}, - {file = "contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339"}, - {file = "contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772"}, - {file = "contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77"}, - {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13"}, - {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe"}, - {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f"}, - {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0"}, - {file = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4"}, - {file = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f"}, - {file = "contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae"}, - {file = "contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc"}, - {file = "contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b"}, - {file = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497"}, - {file = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8"}, - {file = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e"}, - {file = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989"}, - {file = "contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77"}, - {file = "contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880"}, -] - -[package.dependencies] -numpy = ">=1.25" - -[package.extras] -bokeh = ["bokeh", "selenium"] -docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] -mypy = ["bokeh", "contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.17.0)", "types-Pillow"] -test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] -test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] - -[[package]] -name = "coverage" -version = "7.13.0" -description = "Code coverage measurement for Python" -optional = false -python-versions = ">=3.10" -groups = ["test"] -files = [ - {file = "coverage-7.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:02d9fb9eccd48f6843c98a37bd6817462f130b86da8660461e8f5e54d4c06070"}, - {file = "coverage-7.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:367449cf07d33dc216c083f2036bb7d976c6e4903ab31be400ad74ad9f85ce98"}, - {file = "coverage-7.13.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cdb3c9f8fef0a954c632f64328a3935988d33a6604ce4bf67ec3e39670f12ae5"}, - {file = "coverage-7.13.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d10fd186aac2316f9bbb46ef91977f9d394ded67050ad6d84d94ed6ea2e8e54e"}, - {file = "coverage-7.13.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f88ae3e69df2ab62fb0bc5219a597cb890ba5c438190ffa87490b315190bb33"}, - {file = "coverage-7.13.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c4be718e51e86f553bcf515305a158a1cd180d23b72f07ae76d6017c3cc5d791"}, - {file = "coverage-7.13.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a00d3a393207ae12f7c49bb1c113190883b500f48979abb118d8b72b8c95c032"}, - {file = "coverage-7.13.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a7b1cd820e1b6116f92c6128f1188e7afe421c7e1b35fa9836b11444e53ebd9"}, - {file = "coverage-7.13.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:37eee4e552a65866f15dedd917d5e5f3d59805994260720821e2c1b51ac3248f"}, - {file = "coverage-7.13.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:62d7c4f13102148c78d7353c6052af6d899a7f6df66a32bddcc0c0eb7c5326f8"}, - {file = "coverage-7.13.0-cp310-cp310-win32.whl", hash = "sha256:24e4e56304fdb56f96f80eabf840eab043b3afea9348b88be680ec5986780a0f"}, - {file = "coverage-7.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:74c136e4093627cf04b26a35dab8cbfc9b37c647f0502fc313376e11726ba303"}, - {file = "coverage-7.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0dfa3855031070058add1a59fdfda0192fd3e8f97e7c81de0596c145dea51820"}, - {file = "coverage-7.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fdb6f54f38e334db97f72fa0c701e66d8479af0bc3f9bfb5b90f1c30f54500f"}, - {file = "coverage-7.13.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7e442c013447d1d8d195be62852270b78b6e255b79b8675bad8479641e21fd96"}, - {file = "coverage-7.13.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1ed5630d946859de835a85e9a43b721123a8a44ec26e2830b296d478c7fd4259"}, - {file = "coverage-7.13.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f15a931a668e58087bc39d05d2b4bf4b14ff2875b49c994bbdb1c2217a8daeb"}, - {file = "coverage-7.13.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:30a3a201a127ea57f7e14ba43c93c9c4be8b7d17a26e03bb49e6966d019eede9"}, - {file = "coverage-7.13.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a485ff48fbd231efa32d58f479befce52dcb6bfb2a88bb7bf9a0b89b1bc8030"}, - {file = "coverage-7.13.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:22486cdafba4f9e471c816a2a5745337742a617fef68e890d8baf9f3036d7833"}, - {file = "coverage-7.13.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:263c3dbccc78e2e331e59e90115941b5f53e85cfcc6b3b2fbff1fd4e3d2c6ea8"}, - {file = "coverage-7.13.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e5330fa0cc1f5c3c4c3bb8e101b742025933e7848989370a1d4c8c5e401ea753"}, - {file = "coverage-7.13.0-cp311-cp311-win32.whl", hash = "sha256:0f4872f5d6c54419c94c25dd6ae1d015deeb337d06e448cd890a1e89a8ee7f3b"}, - {file = "coverage-7.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51a202e0f80f241ccb68e3e26e19ab5b3bf0f813314f2c967642f13ebcf1ddfe"}, - {file = "coverage-7.13.0-cp311-cp311-win_arm64.whl", hash = "sha256:d2a9d7f1c11487b1c69367ab3ac2d81b9b3721f097aa409a3191c3e90f8f3dd7"}, - {file = "coverage-7.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0b3d67d31383c4c68e19a88e28fc4c2e29517580f1b0ebec4a069d502ce1e0bf"}, - {file = "coverage-7.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:581f086833d24a22c89ae0fe2142cfaa1c92c930adf637ddf122d55083fb5a0f"}, - {file = "coverage-7.13.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0a3a30f0e257df382f5f9534d4ce3d4cf06eafaf5192beb1a7bd066cb10e78fb"}, - {file = "coverage-7.13.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:583221913fbc8f53b88c42e8dbb8fca1d0f2e597cb190ce45916662b8b9d9621"}, - {file = "coverage-7.13.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f5d9bd30756fff3e7216491a0d6d520c448d5124d3d8e8f56446d6412499e74"}, - {file = "coverage-7.13.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a23e5a1f8b982d56fa64f8e442e037f6ce29322f1f9e6c2344cd9e9f4407ee57"}, - {file = "coverage-7.13.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9b01c22bc74a7fb44066aaf765224c0d933ddf1f5047d6cdfe4795504a4493f8"}, - {file = "coverage-7.13.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:898cce66d0836973f48dda4e3514d863d70142bdf6dfab932b9b6a90ea5b222d"}, - {file = "coverage-7.13.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:3ab483ea0e251b5790c2aac03acde31bff0c736bf8a86829b89382b407cd1c3b"}, - {file = "coverage-7.13.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1d84e91521c5e4cb6602fe11ece3e1de03b2760e14ae4fcf1a4b56fa3c801fcd"}, - {file = "coverage-7.13.0-cp312-cp312-win32.whl", hash = "sha256:193c3887285eec1dbdb3f2bd7fbc351d570ca9c02ca756c3afbc71b3c98af6ef"}, - {file = "coverage-7.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:4f3e223b2b2db5e0db0c2b97286aba0036ca000f06aca9b12112eaa9af3d92ae"}, - {file = "coverage-7.13.0-cp312-cp312-win_arm64.whl", hash = "sha256:086cede306d96202e15a4b77ace8472e39d9f4e5f9fd92dd4fecdfb2313b2080"}, - {file = "coverage-7.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:28ee1c96109974af104028a8ef57cec21447d42d0e937c0275329272e370ebcf"}, - {file = "coverage-7.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d1e97353dcc5587b85986cda4ff3ec98081d7e84dd95e8b2a6d59820f0545f8a"}, - {file = "coverage-7.13.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:99acd4dfdfeb58e1937629eb1ab6ab0899b131f183ee5f23e0b5da5cba2fec74"}, - {file = "coverage-7.13.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ff45e0cd8451e293b63ced93161e189780baf444119391b3e7d25315060368a6"}, - {file = "coverage-7.13.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f4f72a85316d8e13234cafe0a9f81b40418ad7a082792fa4165bd7d45d96066b"}, - {file = "coverage-7.13.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:11c21557d0e0a5a38632cbbaca5f008723b26a89d70db6315523df6df77d6232"}, - {file = "coverage-7.13.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76541dc8d53715fb4f7a3a06b34b0dc6846e3c69bc6204c55653a85dd6220971"}, - {file = "coverage-7.13.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6e9e451dee940a86789134b6b0ffbe31c454ade3b849bb8a9d2cca2541a8e91d"}, - {file = "coverage-7.13.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:5c67dace46f361125e6b9cace8fe0b729ed8479f47e70c89b838d319375c8137"}, - {file = "coverage-7.13.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f59883c643cb19630500f57016f76cfdcd6845ca8c5b5ea1f6e17f74c8e5f511"}, - {file = "coverage-7.13.0-cp313-cp313-win32.whl", hash = "sha256:58632b187be6f0be500f553be41e277712baa278147ecb7559983c6d9faf7ae1"}, - {file = "coverage-7.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:73419b89f812f498aca53f757dd834919b48ce4799f9d5cad33ca0ae442bdb1a"}, - {file = "coverage-7.13.0-cp313-cp313-win_arm64.whl", hash = "sha256:eb76670874fdd6091eedcc856128ee48c41a9bbbb9c3f1c7c3cf169290e3ffd6"}, - {file = "coverage-7.13.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6e63ccc6e0ad8986386461c3c4b737540f20426e7ec932f42e030320896c311a"}, - {file = "coverage-7.13.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:494f5459ffa1bd45e18558cd98710c36c0b8fbfa82a5eabcbe671d80ecffbfe8"}, - {file = "coverage-7.13.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:06cac81bf10f74034e055e903f5f946e3e26fc51c09fc9f584e4a1605d977053"}, - {file = "coverage-7.13.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f2ffc92b46ed6e6760f1d47a71e56b5664781bc68986dbd1836b2b70c0ce2071"}, - {file = "coverage-7.13.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0602f701057c6823e5db1b74530ce85f17c3c5be5c85fc042ac939cbd909426e"}, - {file = "coverage-7.13.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:25dc33618d45456ccb1d37bce44bc78cf269909aa14c4db2e03d63146a8a1493"}, - {file = "coverage-7.13.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:71936a8b3b977ddd0b694c28c6a34f4fff2e9dd201969a4ff5d5fc7742d614b0"}, - {file = "coverage-7.13.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:936bc20503ce24770c71938d1369461f0c5320830800933bc3956e2a4ded930e"}, - {file = "coverage-7.13.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:af0a583efaacc52ae2521f8d7910aff65cdb093091d76291ac5820d5e947fc1c"}, - {file = "coverage-7.13.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f1c23e24a7000da892a312fb17e33c5f94f8b001de44b7cf8ba2e36fbd15859e"}, - {file = "coverage-7.13.0-cp313-cp313t-win32.whl", hash = "sha256:5f8a0297355e652001015e93be345ee54393e45dc3050af4a0475c5a2b767d46"}, - {file = "coverage-7.13.0-cp313-cp313t-win_amd64.whl", hash = "sha256:6abb3a4c52f05e08460bd9acf04fec027f8718ecaa0d09c40ffbc3fbd70ecc39"}, - {file = "coverage-7.13.0-cp313-cp313t-win_arm64.whl", hash = "sha256:3ad968d1e3aa6ce5be295ab5fe3ae1bf5bb4769d0f98a80a0252d543a2ef2e9e"}, - {file = "coverage-7.13.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:453b7ec753cf5e4356e14fe858064e5520c460d3bbbcb9c35e55c0d21155c256"}, - {file = "coverage-7.13.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:af827b7cbb303e1befa6c4f94fd2bf72f108089cfa0f8abab8f4ca553cf5ca5a"}, - {file = "coverage-7.13.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9987a9e4f8197a1000280f7cc089e3ea2c8b3c0a64d750537809879a7b4ceaf9"}, - {file = "coverage-7.13.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3188936845cd0cb114fa6a51842a304cdbac2958145d03be2377ec41eb285d19"}, - {file = "coverage-7.13.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2bdb3babb74079f021696cb46b8bb5f5661165c385d3a238712b031a12355be"}, - {file = "coverage-7.13.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7464663eaca6adba4175f6c19354feea61ebbdd735563a03d1e472c7072d27bb"}, - {file = "coverage-7.13.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8069e831f205d2ff1f3d355e82f511eb7c5522d7d413f5db5756b772ec8697f8"}, - {file = "coverage-7.13.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:6fb2d5d272341565f08e962cce14cdf843a08ac43bd621783527adb06b089c4b"}, - {file = "coverage-7.13.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:5e70f92ef89bac1ac8a99b3324923b4749f008fdbd7aa9cb35e01d7a284a04f9"}, - {file = "coverage-7.13.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4b5de7d4583e60d5fd246dd57fcd3a8aa23c6e118a8c72b38adf666ba8e7e927"}, - {file = "coverage-7.13.0-cp314-cp314-win32.whl", hash = "sha256:a6c6e16b663be828a8f0b6c5027d36471d4a9f90d28444aa4ced4d48d7d6ae8f"}, - {file = "coverage-7.13.0-cp314-cp314-win_amd64.whl", hash = "sha256:0900872f2fdb3ee5646b557918d02279dc3af3dfb39029ac4e945458b13f73bc"}, - {file = "coverage-7.13.0-cp314-cp314-win_arm64.whl", hash = "sha256:3a10260e6a152e5f03f26db4a407c4c62d3830b9af9b7c0450b183615f05d43b"}, - {file = "coverage-7.13.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9097818b6cc1cfb5f174e3263eba4a62a17683bcfe5c4b5d07f4c97fa51fbf28"}, - {file = "coverage-7.13.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0018f73dfb4301a89292c73be6ba5f58722ff79f51593352759c1790ded1cabe"}, - {file = "coverage-7.13.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:166ad2a22ee770f5656e1257703139d3533b4a0b6909af67c6b4a3adc1c98657"}, - {file = "coverage-7.13.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f6aaef16d65d1787280943f1c8718dc32e9cf141014e4634d64446702d26e0ff"}, - {file = "coverage-7.13.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e999e2dcc094002d6e2c7bbc1fb85b58ba4f465a760a8014d97619330cdbbbf3"}, - {file = "coverage-7.13.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:00c3d22cf6fb1cf3bf662aaaa4e563be8243a5ed2630339069799835a9cc7f9b"}, - {file = "coverage-7.13.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22ccfe8d9bb0d6134892cbe1262493a8c70d736b9df930f3f3afae0fe3ac924d"}, - {file = "coverage-7.13.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:9372dff5ea15930fea0445eaf37bbbafbc771a49e70c0aeed8b4e2c2614cc00e"}, - {file = "coverage-7.13.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:69ac2c492918c2461bc6ace42d0479638e60719f2a4ef3f0815fa2df88e9f940"}, - {file = "coverage-7.13.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:739c6c051a7540608d097b8e13c76cfa85263ced467168dc6b477bae3df7d0e2"}, - {file = "coverage-7.13.0-cp314-cp314t-win32.whl", hash = "sha256:fe81055d8c6c9de76d60c94ddea73c290b416e061d40d542b24a5871bad498b7"}, - {file = "coverage-7.13.0-cp314-cp314t-win_amd64.whl", hash = "sha256:445badb539005283825959ac9fa4a28f712c214b65af3a2c464f1adc90f5fcbc"}, - {file = "coverage-7.13.0-cp314-cp314t-win_arm64.whl", hash = "sha256:de7f6748b890708578fc4b7bb967d810aeb6fcc9bff4bb77dbca77dab2f9df6a"}, - {file = "coverage-7.13.0-py3-none-any.whl", hash = "sha256:850d2998f380b1e266459ca5b47bc9e7daf9af1d070f66317972f382d46f1904"}, - {file = "coverage-7.13.0.tar.gz", hash = "sha256:a394aa27f2d7ff9bc04cf703817773a59ad6dfbd577032e690f961d2460ee936"}, -] - -[package.extras] -toml = ["tomli ; python_full_version <= \"3.11.0a6\""] - -[[package]] -name = "cycler" -version = "0.12.1" -description = "Composable style cycles" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, - {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, -] - -[package.extras] -docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] -tests = ["pytest", "pytest-cov", "pytest-xdist"] - -[[package]] -name = "debugpy" -version = "1.8.19" -description = "An implementation of the Debug Adapter Protocol for Python" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "debugpy-1.8.19-cp310-cp310-macosx_15_0_x86_64.whl", hash = "sha256:fce6da15d73be5935b4438435c53adb512326a3e11e4f90793ea87cd9f018254"}, - {file = "debugpy-1.8.19-cp310-cp310-manylinux_2_34_x86_64.whl", hash = "sha256:e24b1652a1df1ab04d81e7ead446a91c226de704ff5dde6bd0a0dbaab07aa3f2"}, - {file = "debugpy-1.8.19-cp310-cp310-win32.whl", hash = "sha256:327cb28c3ad9e17bc925efc7f7018195fd4787c2fe4b7af1eec11f1d19bdec62"}, - {file = "debugpy-1.8.19-cp310-cp310-win_amd64.whl", hash = "sha256:b7dd275cf2c99e53adb9654f5ae015f70415bbe2bacbe24cfee30d54b6aa03c5"}, - {file = "debugpy-1.8.19-cp311-cp311-macosx_15_0_universal2.whl", hash = "sha256:c5dcfa21de1f735a4f7ced4556339a109aa0f618d366ede9da0a3600f2516d8b"}, - {file = "debugpy-1.8.19-cp311-cp311-manylinux_2_34_x86_64.whl", hash = "sha256:806d6800246244004625d5222d7765874ab2d22f3ba5f615416cf1342d61c488"}, - {file = "debugpy-1.8.19-cp311-cp311-win32.whl", hash = "sha256:783a519e6dfb1f3cd773a9bda592f4887a65040cb0c7bd38dde410f4e53c40d4"}, - {file = "debugpy-1.8.19-cp311-cp311-win_amd64.whl", hash = "sha256:14035cbdbb1fe4b642babcdcb5935c2da3b1067ac211c5c5a8fdc0bb31adbcaa"}, - {file = "debugpy-1.8.19-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:bccb1540a49cde77edc7ce7d9d075c1dbeb2414751bc0048c7a11e1b597a4c2e"}, - {file = "debugpy-1.8.19-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:e9c68d9a382ec754dc05ed1d1b4ed5bd824b9f7c1a8cd1083adb84b3c93501de"}, - {file = "debugpy-1.8.19-cp312-cp312-win32.whl", hash = "sha256:6599cab8a783d1496ae9984c52cb13b7c4a3bd06a8e6c33446832a5d97ce0bee"}, - {file = "debugpy-1.8.19-cp312-cp312-win_amd64.whl", hash = "sha256:66e3d2fd8f2035a8f111eb127fa508469dfa40928a89b460b41fd988684dc83d"}, - {file = "debugpy-1.8.19-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:91e35db2672a0abaf325f4868fcac9c1674a0d9ad9bb8a8c849c03a5ebba3e6d"}, - {file = "debugpy-1.8.19-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:85016a73ab84dea1c1f1dcd88ec692993bcbe4532d1b49ecb5f3c688ae50c606"}, - {file = "debugpy-1.8.19-cp313-cp313-win32.whl", hash = "sha256:b605f17e89ba0ecee994391194285fada89cee111cfcd29d6f2ee11cbdc40976"}, - {file = "debugpy-1.8.19-cp313-cp313-win_amd64.whl", hash = "sha256:c30639998a9f9cd9699b4b621942c0179a6527f083c72351f95c6ab1728d5b73"}, - {file = "debugpy-1.8.19-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:1e8c4d1bd230067bf1bbcdbd6032e5a57068638eb28b9153d008ecde288152af"}, - {file = "debugpy-1.8.19-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:d40c016c1f538dbf1762936e3aeb43a89b965069d9f60f9e39d35d9d25e6b809"}, - {file = "debugpy-1.8.19-cp314-cp314-win32.whl", hash = "sha256:0601708223fe1cd0e27c6cce67a899d92c7d68e73690211e6788a4b0e1903f5b"}, - {file = "debugpy-1.8.19-cp314-cp314-win_amd64.whl", hash = "sha256:8e19a725f5d486f20e53a1dde2ab8bb2c9607c40c00a42ab646def962b41125f"}, - {file = "debugpy-1.8.19-cp38-cp38-macosx_15_0_x86_64.whl", hash = "sha256:d9b6f633fd2865af2afba2beb0c1819b6ecd4aed1c8f90f5d1bbca3272306b10"}, - {file = "debugpy-1.8.19-cp38-cp38-manylinux_2_34_x86_64.whl", hash = "sha256:a21bfdea088f713df05fa246ba0520f6ba44dd7eaec224742f51987a6979a648"}, - {file = "debugpy-1.8.19-cp38-cp38-win32.whl", hash = "sha256:b1cb98e5325da3059ca24445fca48314bfddfdf65ce1b59ff07055e723f06bd2"}, - {file = "debugpy-1.8.19-cp38-cp38-win_amd64.whl", hash = "sha256:c9b9bf440141a36836bdbe4320a2b126bb38aafa85e1aed05d7bfbb0e2a278bf"}, - {file = "debugpy-1.8.19-cp39-cp39-macosx_15_0_x86_64.whl", hash = "sha256:c047177ab2d286451f242b855b650d313198c4a987140d4b35218b2855a64a4a"}, - {file = "debugpy-1.8.19-cp39-cp39-manylinux_2_34_x86_64.whl", hash = "sha256:4468de0c30012d367944f0eab4ecb8371736e8ef9522a465f61214f344c11183"}, - {file = "debugpy-1.8.19-cp39-cp39-win32.whl", hash = "sha256:7b62c0f015120ede25e5124a5f9d8a424e1208e3d96a36c89958f046ee21fff6"}, - {file = "debugpy-1.8.19-cp39-cp39-win_amd64.whl", hash = "sha256:76f566baaf7f3e06adbe67ffedccd2ee911d1e486f55931939ce3f0fe1090774"}, - {file = "debugpy-1.8.19-py2.py3-none-any.whl", hash = "sha256:360ffd231a780abbc414ba0f005dad409e71c78637efe8f2bd75837132a41d38"}, - {file = "debugpy-1.8.19.tar.gz", hash = "sha256:eea7e5987445ab0b5ed258093722d5ecb8bb72217c5c9b1e21f64efe23ddebdb"}, -] - -[[package]] -name = "decorator" -version = "5.2.1" -description = "Decorators for Humans" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a"}, - {file = "decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360"}, -] - -[[package]] -name = "defusedxml" -version = "0.7.1" -description = "XML bomb protection for Python stdlib modules" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -groups = ["docs"] -files = [ - {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, - {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, -] - -[[package]] -name = "distlib" -version = "0.4.0" -description = "Distribution utilities" -optional = false -python-versions = "*" -groups = ["dev"] -files = [ - {file = "distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16"}, - {file = "distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d"}, -] - -[[package]] -name = "docutils" -version = "0.22.3" -description = "Docutils -- Python Documentation Utilities" -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "docutils-0.22.3-py3-none-any.whl", hash = "sha256:bd772e4aca73aff037958d44f2be5229ded4c09927fcf8690c577b66234d6ceb"}, - {file = "docutils-0.22.3.tar.gz", hash = "sha256:21486ae730e4ca9f622677b1412b879af1791efcfba517e4c6f60be543fc8cdd"}, -] - -[[package]] -name = "executing" -version = "2.2.1" -description = "Get the currently executing AST node of a frame, and other information" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017"}, - {file = "executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4"}, -] - -[package.extras] -tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich ; python_version >= \"3.11\""] - -[[package]] -name = "fastjsonschema" -version = "2.21.2" -description = "Fastest Python implementation of JSON schema" -optional = false -python-versions = "*" -groups = ["docs"] -files = [ - {file = "fastjsonschema-2.21.2-py3-none-any.whl", hash = "sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463"}, - {file = "fastjsonschema-2.21.2.tar.gz", hash = "sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de"}, -] - -[package.extras] -devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] - -[[package]] -name = "filelock" -version = "3.20.3" -description = "A platform independent file lock." -optional = false -python-versions = ">=3.10" -groups = ["dev"] -files = [ - {file = "filelock-3.20.3-py3-none-any.whl", hash = "sha256:4b0dda527ee31078689fc205ec4f1c1bf7d56cf88b6dc9426c4f230e46c2dce1"}, - {file = "filelock-3.20.3.tar.gz", hash = "sha256:18c57ee915c7ec61cff0ecf7f0f869936c7c30191bb0cf406f1341778d0834e1"}, -] - -[[package]] -name = "fonttools" -version = "4.61.1" -description = "Tools to manipulate font files" -optional = false -python-versions = ">=3.10" -groups = ["docs"] -files = [ - {file = "fonttools-4.61.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c7db70d57e5e1089a274cbb2b1fd635c9a24de809a231b154965d415d6c6d24"}, - {file = "fonttools-4.61.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5fe9fd43882620017add5eabb781ebfbc6998ee49b35bd7f8f79af1f9f99a958"}, - {file = "fonttools-4.61.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8db08051fc9e7d8bc622f2112511b8107d8f27cd89e2f64ec45e9825e8288da"}, - {file = "fonttools-4.61.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a76d4cb80f41ba94a6691264be76435e5f72f2cb3cab0b092a6212855f71c2f6"}, - {file = "fonttools-4.61.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a13fc8aeb24bad755eea8f7f9d409438eb94e82cf86b08fe77a03fbc8f6a96b1"}, - {file = "fonttools-4.61.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b846a1fcf8beadeb9ea4f44ec5bdde393e2f1569e17d700bfc49cd69bde75881"}, - {file = "fonttools-4.61.1-cp310-cp310-win32.whl", hash = "sha256:78a7d3ab09dc47ac1a363a493e6112d8cabed7ba7caad5f54dbe2f08676d1b47"}, - {file = "fonttools-4.61.1-cp310-cp310-win_amd64.whl", hash = "sha256:eff1ac3cc66c2ac7cda1e64b4e2f3ffef474b7335f92fc3833fc632d595fcee6"}, - {file = "fonttools-4.61.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c6604b735bb12fef8e0efd5578c9fb5d3d8532d5001ea13a19cddf295673ee09"}, - {file = "fonttools-4.61.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5ce02f38a754f207f2f06557523cd39a06438ba3aafc0639c477ac409fc64e37"}, - {file = "fonttools-4.61.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77efb033d8d7ff233385f30c62c7c79271c8885d5c9657d967ede124671bbdfb"}, - {file = "fonttools-4.61.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:75c1a6dfac6abd407634420c93864a1e274ebc1c7531346d9254c0d8f6ca00f9"}, - {file = "fonttools-4.61.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0de30bfe7745c0d1ffa2b0b7048fb7123ad0d71107e10ee090fa0b16b9452e87"}, - {file = "fonttools-4.61.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:58b0ee0ab5b1fc9921eccfe11d1435added19d6494dde14e323f25ad2bc30c56"}, - {file = "fonttools-4.61.1-cp311-cp311-win32.whl", hash = "sha256:f79b168428351d11e10c5aeb61a74e1851ec221081299f4cf56036a95431c43a"}, - {file = "fonttools-4.61.1-cp311-cp311-win_amd64.whl", hash = "sha256:fe2efccb324948a11dd09d22136fe2ac8a97d6c1347cf0b58a911dcd529f66b7"}, - {file = "fonttools-4.61.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f3cb4a569029b9f291f88aafc927dd53683757e640081ca8c412781ea144565e"}, - {file = "fonttools-4.61.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41a7170d042e8c0024703ed13b71893519a1a6d6e18e933e3ec7507a2c26a4b2"}, - {file = "fonttools-4.61.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10d88e55330e092940584774ee5e8a6971b01fc2f4d3466a1d6c158230880796"}, - {file = "fonttools-4.61.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:15acc09befd16a0fb8a8f62bc147e1a82817542d72184acca9ce6e0aeda9fa6d"}, - {file = "fonttools-4.61.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e6bcdf33aec38d16508ce61fd81838f24c83c90a1d1b8c68982857038673d6b8"}, - {file = "fonttools-4.61.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5fade934607a523614726119164ff621e8c30e8fa1ffffbbd358662056ba69f0"}, - {file = "fonttools-4.61.1-cp312-cp312-win32.whl", hash = "sha256:75da8f28eff26defba42c52986de97b22106cb8f26515b7c22443ebc9c2d3261"}, - {file = "fonttools-4.61.1-cp312-cp312-win_amd64.whl", hash = "sha256:497c31ce314219888c0e2fce5ad9178ca83fe5230b01a5006726cdf3ac9f24d9"}, - {file = "fonttools-4.61.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c56c488ab471628ff3bfa80964372fc13504ece601e0d97a78ee74126b2045c"}, - {file = "fonttools-4.61.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dc492779501fa723b04d0ab1f5be046797fee17d27700476edc7ee9ae535a61e"}, - {file = "fonttools-4.61.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:64102ca87e84261419c3747a0d20f396eb024bdbeb04c2bfb37e2891f5fadcb5"}, - {file = "fonttools-4.61.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c1b526c8d3f615a7b1867f38a9410849c8f4aef078535742198e942fba0e9bd"}, - {file = "fonttools-4.61.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:41ed4b5ec103bd306bb68f81dc166e77409e5209443e5773cb4ed837bcc9b0d3"}, - {file = "fonttools-4.61.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b501c862d4901792adaec7c25b1ecc749e2662543f68bb194c42ba18d6eec98d"}, - {file = "fonttools-4.61.1-cp313-cp313-win32.whl", hash = "sha256:4d7092bb38c53bbc78e9255a59158b150bcdc115a1e3b3ce0b5f267dc35dd63c"}, - {file = "fonttools-4.61.1-cp313-cp313-win_amd64.whl", hash = "sha256:21e7c8d76f62ab13c9472ccf74515ca5b9a761d1bde3265152a6dc58700d895b"}, - {file = "fonttools-4.61.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fff4f534200a04b4a36e7ae3cb74493afe807b517a09e99cb4faa89a34ed6ecd"}, - {file = "fonttools-4.61.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d9203500f7c63545b4ce3799319fe4d9feb1a1b89b28d3cb5abd11b9dd64147e"}, - {file = "fonttools-4.61.1-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fa646ecec9528bef693415c79a86e733c70a4965dd938e9a226b0fc64c9d2e6c"}, - {file = "fonttools-4.61.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11f35ad7805edba3aac1a3710d104592df59f4b957e30108ae0ba6c10b11dd75"}, - {file = "fonttools-4.61.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b931ae8f62db78861b0ff1ac017851764602288575d65b8e8ff1963fed419063"}, - {file = "fonttools-4.61.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b148b56f5de675ee16d45e769e69f87623a4944f7443850bf9a9376e628a89d2"}, - {file = "fonttools-4.61.1-cp314-cp314-win32.whl", hash = "sha256:9b666a475a65f4e839d3d10473fad6d47e0a9db14a2f4a224029c5bfde58ad2c"}, - {file = "fonttools-4.61.1-cp314-cp314-win_amd64.whl", hash = "sha256:4f5686e1fe5fce75d82d93c47a438a25bf0d1319d2843a926f741140b2b16e0c"}, - {file = "fonttools-4.61.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:e76ce097e3c57c4bcb67c5aa24a0ecdbd9f74ea9219997a707a4061fbe2707aa"}, - {file = "fonttools-4.61.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9cfef3ab326780c04d6646f68d4b4742aae222e8b8ea1d627c74e38afcbc9d91"}, - {file = "fonttools-4.61.1-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a75c301f96db737e1c5ed5fd7d77d9c34466de16095a266509e13da09751bd19"}, - {file = "fonttools-4.61.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:91669ccac46bbc1d09e9273546181919064e8df73488ea087dcac3e2968df9ba"}, - {file = "fonttools-4.61.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c33ab3ca9d3ccd581d58e989d67554e42d8d4ded94ab3ade3508455fe70e65f7"}, - {file = "fonttools-4.61.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:664c5a68ec406f6b1547946683008576ef8b38275608e1cee6c061828171c118"}, - {file = "fonttools-4.61.1-cp314-cp314t-win32.whl", hash = "sha256:aed04cabe26f30c1647ef0e8fbb207516fd40fe9472e9439695f5c6998e60ac5"}, - {file = "fonttools-4.61.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2180f14c141d2f0f3da43f3a81bc8aa4684860f6b0e6f9e165a4831f24e6a23b"}, - {file = "fonttools-4.61.1-py3-none-any.whl", hash = "sha256:17d2bf5d541add43822bcf0c43d7d847b160c9bb01d15d5007d84e2217aaa371"}, - {file = "fonttools-4.61.1.tar.gz", hash = "sha256:6675329885c44657f826ef01d9e4fb33b9158e9d93c537d84ad8399539bc6f69"}, -] - -[package.extras] -all = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\"", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.45.0)", "unicodedata2 (>=17.0.0) ; python_version <= \"3.14\"", "xattr ; sys_platform == \"darwin\"", "zopfli (>=0.1.4)"] -graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\""] -lxml = ["lxml (>=4.0)"] -pathops = ["skia-pathops (>=0.5.0)"] -plot = ["matplotlib"] -repacker = ["uharfbuzz (>=0.45.0)"] -symfont = ["sympy"] -type1 = ["xattr ; sys_platform == \"darwin\""] -unicode = ["unicodedata2 (>=17.0.0) ; python_version <= \"3.14\""] -woff = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "zopfli (>=0.1.4)"] - -[[package]] -name = "identify" -version = "2.6.15" -description = "File identification library for Python" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "identify-2.6.15-py2.py3-none-any.whl", hash = "sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757"}, - {file = "identify-2.6.15.tar.gz", hash = "sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf"}, -] - -[package.extras] -license = ["ukkonen"] - -[[package]] -name = "idna" -version = "3.15" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.8" -groups = ["main", "docs", "test"] -files = [ - {file = "idna-3.15-py3-none-any.whl", hash = "sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8"}, - {file = "idna-3.15.tar.gz", hash = "sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc"}, -] - -[package.extras] -all = ["mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "imagesize" -version = "1.4.1" -description = "Getting image size from png/jpeg/jpeg2000/gif file" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -groups = ["docs"] -files = [ - {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, - {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, -] - -[[package]] -name = "iniconfig" -version = "2.3.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.10" -groups = ["dev", "test"] -files = [ - {file = "iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"}, - {file = "iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"}, -] - -[[package]] -name = "ipykernel" -version = "7.1.0" -description = "IPython Kernel for Jupyter" -optional = false -python-versions = ">=3.10" -groups = ["docs"] -files = [ - {file = "ipykernel-7.1.0-py3-none-any.whl", hash = "sha256:763b5ec6c5b7776f6a8d7ce09b267693b4e5ce75cb50ae696aaefb3c85e1ea4c"}, - {file = "ipykernel-7.1.0.tar.gz", hash = "sha256:58a3fc88533d5930c3546dc7eac66c6d288acde4f801e2001e65edc5dc9cf0db"}, -] - -[package.dependencies] -appnope = {version = ">=0.1.2", markers = "platform_system == \"Darwin\""} -comm = ">=0.1.1" -debugpy = ">=1.6.5" -ipython = ">=7.23.1" -jupyter-client = ">=8.0.0" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -matplotlib-inline = ">=0.1" -nest-asyncio = ">=1.4" -packaging = ">=22" -psutil = ">=5.7" -pyzmq = ">=25" -tornado = ">=6.2" -traitlets = ">=5.4.0" - -[package.extras] -cov = ["coverage[toml]", "matplotlib", "pytest-cov", "trio"] -docs = ["intersphinx-registry", "myst-parser", "pydata-sphinx-theme", "sphinx (<8.2.0)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] -pyqt5 = ["pyqt5"] -pyside6 = ["pyside6"] -test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0,<9)", "pytest-asyncio (>=0.23.5)", "pytest-cov", "pytest-timeout"] - -[[package]] -name = "ipython" -version = "9.8.0" -description = "IPython: Productive Interactive Computing" -optional = false -python-versions = ">=3.11" -groups = ["docs"] -files = [ - {file = "ipython-9.8.0-py3-none-any.whl", hash = "sha256:ebe6d1d58d7d988fbf23ff8ff6d8e1622cfdb194daf4b7b73b792c4ec3b85385"}, - {file = "ipython-9.8.0.tar.gz", hash = "sha256:8e4ce129a627eb9dd221c41b1d2cdaed4ef7c9da8c17c63f6f578fe231141f83"}, -] - -[package.dependencies] -colorama = {version = ">=0.4.4", markers = "sys_platform == \"win32\""} -decorator = ">=4.3.2" -ipython-pygments-lexers = ">=1.0.0" -jedi = ">=0.18.1" -matplotlib-inline = ">=0.1.5" -pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""} -prompt_toolkit = ">=3.0.41,<3.1.0" -pygments = ">=2.11.0" -stack_data = ">=0.6.0" -traitlets = ">=5.13.0" -typing_extensions = {version = ">=4.6", markers = "python_version < \"3.12\""} - -[package.extras] -all = ["ipython[doc,matplotlib,test,test-extra]"] -black = ["black"] -doc = ["docrepr", "exceptiongroup", "intersphinx_registry", "ipykernel", "ipython[matplotlib,test]", "setuptools (>=70.0)", "sphinx (>=8.0)", "sphinx-rtd-theme (>=0.1.8)", "sphinx_toml (==0.0.4)", "typing_extensions"] -matplotlib = ["matplotlib (>3.9)"] -test = ["packaging (>=20.1.0)", "pytest (>=7.0.0)", "pytest-asyncio (>=1.0.0)", "setuptools (>=61.2)", "testpath (>=0.2)"] -test-extra = ["curio", "ipykernel (>6.30)", "ipython[matplotlib]", "ipython[test]", "jupyter_ai", "nbclient", "nbformat", "numpy (>=1.27)", "pandas (>2.1)", "trio (>=0.1.0)"] - -[[package]] -name = "ipython-pygments-lexers" -version = "1.1.1" -description = "Defines a variety of Pygments lexers for highlighting IPython code." -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c"}, - {file = "ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81"}, -] - -[package.dependencies] -pygments = "*" - -[[package]] -name = "jedi" -version = "0.19.2" -description = "An autocompletion tool for Python that can be used for text editors." -optional = false -python-versions = ">=3.6" -groups = ["docs"] -files = [ - {file = "jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9"}, - {file = "jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0"}, -] - -[package.dependencies] -parso = ">=0.8.4,<0.9.0" - -[package.extras] -docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] -qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["Django", "attrs", "colorama", "docopt", "pytest (<9.0.0)"] - -[[package]] -name = "jinja2" -version = "3.1.6" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -groups = ["docs"] -files = [ - {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, - {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "jmespath" -version = "1.1.0" -description = "JSON Matching Expressions" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "jmespath-1.1.0-py3-none-any.whl", hash = "sha256:a5663118de4908c91729bea0acadca56526eb2698e83de10cd116ae0f4e97c64"}, - {file = "jmespath-1.1.0.tar.gz", hash = "sha256:472c87d80f36026ae83c6ddd0f1d05d4e510134ed462851fd5f754c8c3cbb88d"}, -] - -[[package]] -name = "jsonschema" -version = "4.25.1" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "jsonschema-4.25.1-py3-none-any.whl", hash = "sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63"}, - {file = "jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85"}, -] - -[package.dependencies] -attrs = ">=22.2.0" -jsonschema-specifications = ">=2023.03.6" -referencing = ">=0.28.4" -rpds-py = ">=0.7.1" - -[package.extras] -format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "rfc3987-syntax (>=1.1.0)", "uri-template", "webcolors (>=24.6.0)"] - -[[package]] -name = "jsonschema-specifications" -version = "2025.9.1" -description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe"}, - {file = "jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d"}, -] - -[package.dependencies] -referencing = ">=0.31.0" - -[[package]] -name = "jupyter-client" -version = "8.7.0" -description = "Jupyter protocol implementation and client libraries" -optional = false -python-versions = ">=3.10" -groups = ["docs"] -files = [ - {file = "jupyter_client-8.7.0-py3-none-any.whl", hash = "sha256:3671a94fd25e62f5f2f554f5e95389c2294d89822378a5f2dd24353e1494a9e0"}, - {file = "jupyter_client-8.7.0.tar.gz", hash = "sha256:3357212d9cbe01209e59190f67a3a7e1f387a4f4e88d1e0433ad84d7b262531d"}, -] - -[package.dependencies] -jupyter-core = ">=5.1" -python-dateutil = ">=2.8.2" -pyzmq = ">=25.0" -tornado = ">=6.4.1" -traitlets = ">=5.3" - -[package.extras] -docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["anyio", "coverage", "ipykernel (>=6.14)", "mypy", "paramiko ; sys_platform == \"win32\"", "pre-commit", "pytest", "pytest-cov", "pytest-jupyter[client] (>=0.6.2)", "pytest-timeout"] - -[[package]] -name = "jupyter-core" -version = "5.9.1" -description = "Jupyter core package. A base package on which Jupyter projects rely." -optional = false -python-versions = ">=3.10" -groups = ["docs"] -files = [ - {file = "jupyter_core-5.9.1-py3-none-any.whl", hash = "sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407"}, - {file = "jupyter_core-5.9.1.tar.gz", hash = "sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508"}, -] - -[package.dependencies] -platformdirs = ">=2.5" -traitlets = ">=5.3" - -[package.extras] -docs = ["intersphinx-registry", "myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-spelling", "traitlets"] -test = ["ipykernel", "pre-commit", "pytest (<9)", "pytest-cov", "pytest-timeout"] - -[[package]] -name = "jupyterlab-pygments" -version = "0.3.0" -description = "Pygments theme using JupyterLab CSS variables" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780"}, - {file = "jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d"}, -] - -[[package]] -name = "kiwisolver" -version = "1.4.9" -description = "A fast implementation of the Cassowary constraint solver" -optional = false -python-versions = ">=3.10" -groups = ["docs"] -files = [ - {file = "kiwisolver-1.4.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b4b4d74bda2b8ebf4da5bd42af11d02d04428b2c32846e4c2c93219df8a7987b"}, - {file = "kiwisolver-1.4.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fb3b8132019ea572f4611d770991000d7f58127560c4889729248eb5852a102f"}, - {file = "kiwisolver-1.4.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84fd60810829c27ae375114cd379da1fa65e6918e1da405f356a775d49a62bcf"}, - {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b78efa4c6e804ecdf727e580dbb9cba85624d2e1c6b5cb059c66290063bd99a9"}, - {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4efec7bcf21671db6a3294ff301d2fc861c31faa3c8740d1a94689234d1b415"}, - {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:90f47e70293fc3688b71271100a1a5453aa9944a81d27ff779c108372cf5567b"}, - {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8fdca1def57a2e88ef339de1737a1449d6dbf5fab184c54a1fca01d541317154"}, - {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9cf554f21be770f5111a1690d42313e140355e687e05cf82cb23d0a721a64a48"}, - {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fc1795ac5cd0510207482c3d1d3ed781143383b8cfd36f5c645f3897ce066220"}, - {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ccd09f20ccdbbd341b21a67ab50a119b64a403b09288c27481575105283c1586"}, - {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:540c7c72324d864406a009d72f5d6856f49693db95d1fbb46cf86febef873634"}, - {file = "kiwisolver-1.4.9-cp310-cp310-win_amd64.whl", hash = "sha256:ede8c6d533bc6601a47ad4046080d36b8fc99f81e6f1c17b0ac3c2dc91ac7611"}, - {file = "kiwisolver-1.4.9-cp310-cp310-win_arm64.whl", hash = "sha256:7b4da0d01ac866a57dd61ac258c5607b4cd677f63abaec7b148354d2b2cdd536"}, - {file = "kiwisolver-1.4.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb14a5da6dc7642b0f3a18f13654847cd8b7a2550e2645a5bda677862b03ba16"}, - {file = "kiwisolver-1.4.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:39a219e1c81ae3b103643d2aedb90f1ef22650deb266ff12a19e7773f3e5f089"}, - {file = "kiwisolver-1.4.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2405a7d98604b87f3fc28b1716783534b1b4b8510d8142adca34ee0bc3c87543"}, - {file = "kiwisolver-1.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dc1ae486f9abcef254b5618dfb4113dd49f94c68e3e027d03cf0143f3f772b61"}, - {file = "kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a1f570ce4d62d718dce3f179ee78dac3b545ac16c0c04bb363b7607a949c0d1"}, - {file = "kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb27e7b78d716c591e88e0a09a2139c6577865d7f2e152488c2cc6257f460872"}, - {file = "kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:15163165efc2f627eb9687ea5f3a28137217d217ac4024893d753f46bce9de26"}, - {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bdee92c56a71d2b24c33a7d4c2856bd6419d017e08caa7802d2963870e315028"}, - {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:412f287c55a6f54b0650bd9b6dce5aceddb95864a1a90c87af16979d37c89771"}, - {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2c93f00dcba2eea70af2be5f11a830a742fe6b579a1d4e00f47760ef13be247a"}, - {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f117e1a089d9411663a3207ba874f31be9ac8eaa5b533787024dc07aeb74f464"}, - {file = "kiwisolver-1.4.9-cp311-cp311-win_amd64.whl", hash = "sha256:be6a04e6c79819c9a8c2373317d19a96048e5a3f90bec587787e86a1153883c2"}, - {file = "kiwisolver-1.4.9-cp311-cp311-win_arm64.whl", hash = "sha256:0ae37737256ba2de764ddc12aed4956460277f00c4996d51a197e72f62f5eec7"}, - {file = "kiwisolver-1.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ac5a486ac389dddcc5bef4f365b6ae3ffff2c433324fb38dd35e3fab7c957999"}, - {file = "kiwisolver-1.4.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2ba92255faa7309d06fe44c3a4a97efe1c8d640c2a79a5ef728b685762a6fd2"}, - {file = "kiwisolver-1.4.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a2899935e724dd1074cb568ce7ac0dce28b2cd6ab539c8e001a8578eb106d14"}, - {file = "kiwisolver-1.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f6008a4919fdbc0b0097089f67a1eb55d950ed7e90ce2cc3e640abadd2757a04"}, - {file = "kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67bb8b474b4181770f926f7b7d2f8c0248cbcb78b660fdd41a47054b28d2a752"}, - {file = "kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2327a4a30d3ee07d2fbe2e7933e8a37c591663b96ce42a00bc67461a87d7df77"}, - {file = "kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a08b491ec91b1d5053ac177afe5290adacf1f0f6307d771ccac5de30592d198"}, - {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8fc5c867c22b828001b6a38d2eaeb88160bf5783c6cb4a5e440efc981ce286d"}, - {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3b3115b2581ea35bb6d1f24a4c90af37e5d9b49dcff267eeed14c3893c5b86ab"}, - {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858e4c22fb075920b96a291928cb7dea5644e94c0ee4fcd5af7e865655e4ccf2"}, - {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ed0fecd28cc62c54b262e3736f8bb2512d8dcfdc2bcf08be5f47f96bf405b145"}, - {file = "kiwisolver-1.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:f68208a520c3d86ea51acf688a3e3002615a7f0238002cccc17affecc86a8a54"}, - {file = "kiwisolver-1.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:2c1a4f57df73965f3f14df20b80ee29e6a7930a57d2d9e8491a25f676e197c60"}, - {file = "kiwisolver-1.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a5d0432ccf1c7ab14f9949eec60c5d1f924f17c037e9f8b33352fa05799359b8"}, - {file = "kiwisolver-1.4.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efb3a45b35622bb6c16dbfab491a8f5a391fe0e9d45ef32f4df85658232ca0e2"}, - {file = "kiwisolver-1.4.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1a12cf6398e8a0a001a059747a1cbf24705e18fe413bc22de7b3d15c67cffe3f"}, - {file = "kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098"}, - {file = "kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5656aa670507437af0207645273ccdfee4f14bacd7f7c67a4306d0dcaeaf6eed"}, - {file = "kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bfc08add558155345129c7803b3671cf195e6a56e7a12f3dde7c57d9b417f525"}, - {file = "kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:40092754720b174e6ccf9e845d0d8c7d8e12c3d71e7fc35f55f3813e96376f78"}, - {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:497d05f29a1300d14e02e6441cf0f5ee81c1ff5a304b0d9fb77423974684e08b"}, - {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdd1a81a1860476eb41ac4bc1e07b3f07259e6d55bbf739b79c8aaedcf512799"}, - {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e6b93f13371d341afee3be9f7c5964e3fe61d5fa30f6a30eb49856935dfe4fc3"}, - {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d75aa530ccfaa593da12834b86a0724f58bff12706659baa9227c2ccaa06264c"}, - {file = "kiwisolver-1.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:dd0a578400839256df88c16abddf9ba14813ec5f21362e1fe65022e00c883d4d"}, - {file = "kiwisolver-1.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:d4188e73af84ca82468f09cadc5ac4db578109e52acb4518d8154698d3a87ca2"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:5a0f2724dfd4e3b3ac5a82436a8e6fd16baa7d507117e4279b660fe8ca38a3a1"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1b11d6a633e4ed84fc0ddafd4ebfd8ea49b3f25082c04ad12b8315c11d504dc1"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61874cdb0a36016354853593cffc38e56fc9ca5aa97d2c05d3dcf6922cd55a11"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:60c439763a969a6af93b4881db0eed8fadf93ee98e18cbc35bc8da868d0c4f0c"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92a2f997387a1b79a75e7803aa7ded2cfbe2823852ccf1ba3bcf613b62ae3197"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31d512c812daea6d8b3be3b2bfcbeb091dbb09177706569bcfc6240dcf8b41c"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:52a15b0f35dad39862d376df10c5230155243a2c1a436e39eb55623ccbd68185"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a30fd6fdef1430fd9e1ba7b3398b5ee4e2887783917a687d86ba69985fb08748"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cc9617b46837c6468197b5945e196ee9ca43057bb7d9d1ae688101e4e1dddf64"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:0ab74e19f6a2b027ea4f845a78827969af45ce790e6cb3e1ebab71bdf9f215ff"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dba5ee5d3981160c28d5490f0d1b7ed730c22470ff7f6cc26cfcfaacb9896a07"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-win_arm64.whl", hash = "sha256:0749fd8f4218ad2e851e11cc4dc05c7cbc0cbc4267bdfdb31782e65aace4ee9c"}, - {file = "kiwisolver-1.4.9-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:9928fe1eb816d11ae170885a74d074f57af3a0d65777ca47e9aeb854a1fba386"}, - {file = "kiwisolver-1.4.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d0005b053977e7b43388ddec89fa567f43d4f6d5c2c0affe57de5ebf290dc552"}, - {file = "kiwisolver-1.4.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2635d352d67458b66fd0667c14cb1d4145e9560d503219034a18a87e971ce4f3"}, - {file = "kiwisolver-1.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:767c23ad1c58c9e827b649a9ab7809fd5fd9db266a9cf02b0e926ddc2c680d58"}, - {file = "kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72d0eb9fba308b8311685c2268cf7d0a0639a6cd027d8128659f72bdd8a024b4"}, - {file = "kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f68e4f3eeca8fb22cc3d731f9715a13b652795ef657a13df1ad0c7dc0e9731df"}, - {file = "kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d84cd4061ae292d8ac367b2c3fa3aad11cb8625a95d135fe93f286f914f3f5a6"}, - {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a60ea74330b91bd22a29638940d115df9dc00af5035a9a2a6ad9399ffb4ceca5"}, - {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ce6a3a4e106cf35c2d9c4fa17c05ce0b180db622736845d4315519397a77beaf"}, - {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:77937e5e2a38a7b48eef0585114fe7930346993a88060d0bf886086d2aa49ef5"}, - {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:24c175051354f4a28c5d6a31c93906dc653e2bf234e8a4bbfb964892078898ce"}, - {file = "kiwisolver-1.4.9-cp314-cp314-win_amd64.whl", hash = "sha256:0763515d4df10edf6d06a3c19734e2566368980d21ebec439f33f9eb936c07b7"}, - {file = "kiwisolver-1.4.9-cp314-cp314-win_arm64.whl", hash = "sha256:0e4e2bf29574a6a7b7f6cb5fa69293b9f96c928949ac4a53ba3f525dffb87f9c"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d976bbb382b202f71c67f77b0ac11244021cfa3f7dfd9e562eefcea2df711548"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2489e4e5d7ef9a1c300a5e0196e43d9c739f066ef23270607d45aba368b91f2d"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e2ea9f7ab7fbf18fffb1b5434ce7c69a07582f7acc7717720f1d69f3e806f90c"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b34e51affded8faee0dfdb705416153819d8ea9250bbbf7ea1b249bdeb5f1122"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8aacd3d4b33b772542b2e01beb50187536967b514b00003bdda7589722d2a64"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7cf974dd4e35fa315563ac99d6287a1024e4dc2077b8a7d7cd3d2fb65d283134"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:85bd218b5ecfbee8c8a82e121802dcb519a86044c9c3b2e4aef02fa05c6da370"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0856e241c2d3df4efef7c04a1e46b1936b6120c9bcf36dd216e3acd84bc4fb21"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9af39d6551f97d31a4deebeac6f45b156f9755ddc59c07b402c148f5dbb6482a"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:bb4ae2b57fc1d8cbd1cf7b1d9913803681ffa903e7488012be5b76dedf49297f"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:aedff62918805fb62d43a4aa2ecd4482c380dc76cd31bd7c8878588a61bd0369"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:1fa333e8b2ce4d9660f2cda9c0e1b6bafcfb2457a9d259faa82289e73ec24891"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:4a48a2ce79d65d363597ef7b567ce3d14d68783d2b2263d98db3d9477805ba32"}, - {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4d1d9e582ad4d63062d34077a9a1e9f3c34088a2ec5135b1f7190c07cf366527"}, - {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:deed0c7258ceb4c44ad5ec7d9918f9f14fd05b2be86378d86cf50e63d1e7b771"}, - {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0a590506f303f512dff6b7f75fd2fd18e16943efee932008fe7140e5fa91d80e"}, - {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e09c2279a4d01f099f52d5c4b3d9e208e91edcbd1a175c9662a8b16e000fece9"}, - {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c9e7cdf45d594ee04d5be1b24dd9d49f3d1590959b2271fb30b5ca2b262c00fb"}, - {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:720e05574713db64c356e86732c0f3c5252818d05f9df320f0ad8380641acea5"}, - {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:17680d737d5335b552994a2008fab4c851bcd7de33094a82067ef3a576ff02fa"}, - {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:85b5352f94e490c028926ea567fc569c52ec79ce131dadb968d3853e809518c2"}, - {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:464415881e4801295659462c49461a24fb107c140de781d55518c4b80cb6790f"}, - {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:fb940820c63a9590d31d88b815e7a3aa5915cad3ce735ab45f0c730b39547de1"}, - {file = "kiwisolver-1.4.9.tar.gz", hash = "sha256:c3b22c26c6fd6811b0ae8363b95ca8ce4ea3c202d3d0975b2914310ceb1bcc4d"}, -] - -[[package]] -name = "markupsafe" -version = "3.0.3" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559"}, - {file = "markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419"}, - {file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695"}, - {file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591"}, - {file = "markupsafe-3.0.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c"}, - {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f"}, - {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6"}, - {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1"}, - {file = "markupsafe-3.0.3-cp310-cp310-win32.whl", hash = "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa"}, - {file = "markupsafe-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8"}, - {file = "markupsafe-3.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1"}, - {file = "markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad"}, - {file = "markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a"}, - {file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50"}, - {file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf"}, - {file = "markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f"}, - {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a"}, - {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115"}, - {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a"}, - {file = "markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19"}, - {file = "markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01"}, - {file = "markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c"}, - {file = "markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e"}, - {file = "markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce"}, - {file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d"}, - {file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d"}, - {file = "markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a"}, - {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b"}, - {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f"}, - {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b"}, - {file = "markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d"}, - {file = "markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c"}, - {file = "markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f"}, - {file = "markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795"}, - {file = "markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219"}, - {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6"}, - {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676"}, - {file = "markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9"}, - {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1"}, - {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc"}, - {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12"}, - {file = "markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed"}, - {file = "markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5"}, - {file = "markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485"}, - {file = "markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73"}, - {file = "markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37"}, - {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19"}, - {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025"}, - {file = "markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6"}, - {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f"}, - {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb"}, - {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009"}, - {file = "markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354"}, - {file = "markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218"}, - {file = "markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287"}, - {file = "markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe"}, - {file = "markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026"}, - {file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737"}, - {file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97"}, - {file = "markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d"}, - {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda"}, - {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf"}, - {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe"}, - {file = "markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9"}, - {file = "markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581"}, - {file = "markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4"}, - {file = "markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab"}, - {file = "markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175"}, - {file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634"}, - {file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50"}, - {file = "markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e"}, - {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5"}, - {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523"}, - {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc"}, - {file = "markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d"}, - {file = "markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9"}, - {file = "markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa"}, - {file = "markupsafe-3.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15d939a21d546304880945ca1ecb8a039db6b4dc49b2c5a400387cdae6a62e26"}, - {file = "markupsafe-3.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc"}, - {file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f4b68347f8c5eab4a13419215bdfd7f8c9b19f2b25520968adfad23eb0ce60c"}, - {file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8fc20152abba6b83724d7ff268c249fa196d8259ff481f3b1476383f8f24e42"}, - {file = "markupsafe-3.0.3-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:949b8d66bc381ee8b007cd945914c721d9aba8e27f71959d750a46f7c282b20b"}, - {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3537e01efc9d4dccdf77221fb1cb3b8e1a38d5428920e0657ce299b20324d758"}, - {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:591ae9f2a647529ca990bc681daebdd52c8791ff06c2bfa05b65163e28102ef2"}, - {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a320721ab5a1aba0a233739394eb907f8c8da5c98c9181d1161e77a0c8e36f2d"}, - {file = "markupsafe-3.0.3-cp39-cp39-win32.whl", hash = "sha256:df2449253ef108a379b8b5d6b43f4b1a8e81a061d6537becd5582fba5f9196d7"}, - {file = "markupsafe-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:7c3fb7d25180895632e5d3148dbdc29ea38ccb7fd210aa27acbd1201a1902c6e"}, - {file = "markupsafe-3.0.3-cp39-cp39-win_arm64.whl", hash = "sha256:38664109c14ffc9e7437e86b4dceb442b0096dfe3541d7864d9cbe1da4cf36c8"}, - {file = "markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698"}, -] - -[[package]] -name = "matplotlib" -version = "3.10.8" -description = "Python plotting package" -optional = false -python-versions = ">=3.10" -groups = ["docs"] -files = [ - {file = "matplotlib-3.10.8-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:00270d217d6b20d14b584c521f810d60c5c78406dc289859776550df837dcda7"}, - {file = "matplotlib-3.10.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37b3c1cc42aa184b3f738cfa18c1c1d72fd496d85467a6cf7b807936d39aa656"}, - {file = "matplotlib-3.10.8-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ee40c27c795bda6a5292e9cff9890189d32f7e3a0bf04e0e3c9430c4a00c37df"}, - {file = "matplotlib-3.10.8-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a48f2b74020919552ea25d222d5cc6af9ca3f4eb43a93e14d068457f545c2a17"}, - {file = "matplotlib-3.10.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f254d118d14a7f99d616271d6c3c27922c092dac11112670b157798b89bf4933"}, - {file = "matplotlib-3.10.8-cp310-cp310-win_amd64.whl", hash = "sha256:f9b587c9c7274c1613a30afabf65a272114cd6cdbe67b3406f818c79d7ab2e2a"}, - {file = "matplotlib-3.10.8-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6be43b667360fef5c754dda5d25a32e6307a03c204f3c0fc5468b78fa87b4160"}, - {file = "matplotlib-3.10.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2b336e2d91a3d7006864e0990c83b216fcdca64b5a6484912902cef87313d78"}, - {file = "matplotlib-3.10.8-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:efb30e3baaea72ce5928e32bab719ab4770099079d66726a62b11b1ef7273be4"}, - {file = "matplotlib-3.10.8-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d56a1efd5bfd61486c8bc968fa18734464556f0fb8e51690f4ac25d85cbbbbc2"}, - {file = "matplotlib-3.10.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:238b7ce5717600615c895050239ec955d91f321c209dd110db988500558e70d6"}, - {file = "matplotlib-3.10.8-cp311-cp311-win_amd64.whl", hash = "sha256:18821ace09c763ec93aef5eeff087ee493a24051936d7b9ebcad9662f66501f9"}, - {file = "matplotlib-3.10.8-cp311-cp311-win_arm64.whl", hash = "sha256:bab485bcf8b1c7d2060b4fcb6fc368a9e6f4cd754c9c2fea281f4be21df394a2"}, - {file = "matplotlib-3.10.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:64fcc24778ca0404ce0cb7b6b77ae1f4c7231cdd60e6778f999ee05cbd581b9a"}, - {file = "matplotlib-3.10.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b9a5ca4ac220a0cdd1ba6bcba3608547117d30468fefce49bb26f55c1a3d5c58"}, - {file = "matplotlib-3.10.8-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3ab4aabc72de4ff77b3ec33a6d78a68227bf1123465887f9905ba79184a1cc04"}, - {file = "matplotlib-3.10.8-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:24d50994d8c5816ddc35411e50a86ab05f575e2530c02752e02538122613371f"}, - {file = "matplotlib-3.10.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:99eefd13c0dc3b3c1b4d561c1169e65fe47aab7b8158754d7c084088e2329466"}, - {file = "matplotlib-3.10.8-cp312-cp312-win_amd64.whl", hash = "sha256:dd80ecb295460a5d9d260df63c43f4afbdd832d725a531f008dad1664f458adf"}, - {file = "matplotlib-3.10.8-cp312-cp312-win_arm64.whl", hash = "sha256:3c624e43ed56313651bc18a47f838b60d7b8032ed348911c54906b130b20071b"}, - {file = "matplotlib-3.10.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3f2e409836d7f5ac2f1c013110a4d50b9f7edc26328c108915f9075d7d7a91b6"}, - {file = "matplotlib-3.10.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56271f3dac49a88d7fca5060f004d9d22b865f743a12a23b1e937a0be4818ee1"}, - {file = "matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486"}, - {file = "matplotlib-3.10.8-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:646d95230efb9ca614a7a594d4fcacde0ac61d25e37dd51710b36477594963ce"}, - {file = "matplotlib-3.10.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f89c151aab2e2e23cb3fe0acad1e8b82841fd265379c4cecd0f3fcb34c15e0f6"}, - {file = "matplotlib-3.10.8-cp313-cp313-win_amd64.whl", hash = "sha256:e8ea3e2d4066083e264e75c829078f9e149fa119d27e19acd503de65e0b13149"}, - {file = "matplotlib-3.10.8-cp313-cp313-win_arm64.whl", hash = "sha256:c108a1d6fa78a50646029cb6d49808ff0fc1330fda87fa6f6250c6b5369b6645"}, - {file = "matplotlib-3.10.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ad3d9833a64cf48cc4300f2b406c3d0f4f4724a91c0bd5640678a6ba7c102077"}, - {file = "matplotlib-3.10.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:eb3823f11823deade26ce3b9f40dcb4a213da7a670013929f31d5f5ed1055b22"}, - {file = "matplotlib-3.10.8-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d9050fee89a89ed57b4fb2c1bfac9a3d0c57a0d55aed95949eedbc42070fea39"}, - {file = "matplotlib-3.10.8-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b44d07310e404ba95f8c25aa5536f154c0a8ec473303535949e52eb71d0a1565"}, - {file = "matplotlib-3.10.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0a33deb84c15ede243aead39f77e990469fff93ad1521163305095b77b72ce4a"}, - {file = "matplotlib-3.10.8-cp313-cp313t-win_amd64.whl", hash = "sha256:3a48a78d2786784cc2413e57397981fb45c79e968d99656706018d6e62e57958"}, - {file = "matplotlib-3.10.8-cp313-cp313t-win_arm64.whl", hash = "sha256:15d30132718972c2c074cd14638c7f4592bd98719e2308bccea40e0538bc0cb5"}, - {file = "matplotlib-3.10.8-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b53285e65d4fa4c86399979e956235deb900be5baa7fc1218ea67fbfaeaadd6f"}, - {file = "matplotlib-3.10.8-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:32f8dce744be5569bebe789e46727946041199030db8aeb2954d26013a0eb26b"}, - {file = "matplotlib-3.10.8-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cf267add95b1c88300d96ca837833d4112756045364f5c734a2276038dae27d"}, - {file = "matplotlib-3.10.8-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2cf5bd12cecf46908f286d7838b2abc6c91cda506c0445b8223a7c19a00df008"}, - {file = "matplotlib-3.10.8-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:41703cc95688f2516b480f7f339d8851a6035f18e100ee6a32bc0b8536a12a9c"}, - {file = "matplotlib-3.10.8-cp314-cp314-win_amd64.whl", hash = "sha256:83d282364ea9f3e52363da262ce32a09dfe241e4080dcedda3c0db059d3c1f11"}, - {file = "matplotlib-3.10.8-cp314-cp314-win_arm64.whl", hash = "sha256:2c1998e92cd5999e295a731bcb2911c75f597d937341f3030cc24ef2733d78a8"}, - {file = "matplotlib-3.10.8-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b5a2b97dbdc7d4f353ebf343744f1d1f1cca8aa8bfddb4262fcf4306c3761d50"}, - {file = "matplotlib-3.10.8-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3f5c3e4da343bba819f0234186b9004faba952cc420fbc522dc4e103c1985908"}, - {file = "matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f62550b9a30afde8c1c3ae450e5eb547d579dd69b25c2fc7a1c67f934c1717a"}, - {file = "matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:495672de149445ec1b772ff2c9ede9b769e3cb4f0d0aa7fa730d7f59e2d4e1c1"}, - {file = "matplotlib-3.10.8-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:595ba4d8fe983b88f0eec8c26a241e16d6376fe1979086232f481f8f3f67494c"}, - {file = "matplotlib-3.10.8-cp314-cp314t-win_amd64.whl", hash = "sha256:25d380fe8b1dc32cf8f0b1b448470a77afb195438bafdf1d858bfb876f3edf7b"}, - {file = "matplotlib-3.10.8-cp314-cp314t-win_arm64.whl", hash = "sha256:113bb52413ea508ce954a02c10ffd0d565f9c3bc7f2eddc27dfe1731e71c7b5f"}, - {file = "matplotlib-3.10.8-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f97aeb209c3d2511443f8797e3e5a569aebb040d4f8bc79aa3ee78a8fb9e3dd8"}, - {file = "matplotlib-3.10.8-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fb061f596dad3a0f52b60dc6a5dec4a0c300dec41e058a7efe09256188d170b7"}, - {file = "matplotlib-3.10.8-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:12d90df9183093fcd479f4172ac26b322b1248b15729cb57f42f71f24c7e37a3"}, - {file = "matplotlib-3.10.8-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:6da7c2ce169267d0d066adcf63758f0604aa6c3eebf67458930f9d9b79ad1db1"}, - {file = "matplotlib-3.10.8-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9153c3292705be9f9c64498a8872118540c3f4123d1a1c840172edf262c8be4a"}, - {file = "matplotlib-3.10.8-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ae029229a57cd1e8fe542485f27e7ca7b23aa9e8944ddb4985d0bc444f1eca2"}, - {file = "matplotlib-3.10.8.tar.gz", hash = "sha256:2299372c19d56bcd35cf05a2738308758d32b9eaed2371898d8f5bd33f084aa3"}, -] - -[package.dependencies] -contourpy = ">=1.0.1" -cycler = ">=0.10" -fonttools = ">=4.22.0" -kiwisolver = ">=1.3.1" -numpy = ">=1.23" -packaging = ">=20.0" -pillow = ">=8" -pyparsing = ">=3" -python-dateutil = ">=2.7" - -[package.extras] -dev = ["meson-python (>=0.13.1,<0.17.0)", "pybind11 (>=2.13.2,!=2.13.3)", "setuptools (>=64)", "setuptools_scm (>=7)"] - -[[package]] -name = "matplotlib-inline" -version = "0.2.1" -description = "Inline Matplotlib backend for Jupyter" -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "matplotlib_inline-0.2.1-py3-none-any.whl", hash = "sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76"}, - {file = "matplotlib_inline-0.2.1.tar.gz", hash = "sha256:e1ee949c340d771fc39e241ea75683deb94762c8fa5f2927ec57c83c4dffa9fe"}, -] - -[package.dependencies] -traitlets = "*" - -[package.extras] -test = ["flake8", "nbdime", "nbval", "notebook", "pytest"] - -[[package]] -name = "mistune" -version = "3.3.0" -description = "A sane and fast Markdown parser with useful plugins and renderers" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "mistune-3.3.0-py3-none-any.whl", hash = "sha256:a758e578acda49d8195f9a860b132dae2cf7bf409381393b1c4e6e489a65397b"}, - {file = "mistune-3.3.0.tar.gz", hash = "sha256:3074ec4c61b384abe725128e4dcbb483f5a09cc4632012505cdee655d3a113b9"}, -] - -[[package]] -name = "mypy-extensions" -version = "1.1.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, - {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, -] - -[[package]] -name = "nb2plots" -version = "0.7.2" -description = "Converting between ipython notebooks and sphinx docs" -optional = false -python-versions = ">=3.7" -groups = ["docs"] -files = [ - {file = "nb2plots-0.7.2.tar.gz", hash = "sha256:4f0de757fce4d4f6937ebfa2ffbabb7feb87134c61c944055e95a1999aab2d8b"}, -] - -[package.dependencies] -ipython = {version = ">=7.16.3", extras = ["notebook"]} -matplotlib = ">=3.2" -nbconvert = ">=6.0.7" -numpy = ">=1.20" -sphinx = ">=4" -sphinxtesters = ">=0.2.3" -texext = ">=0.6.6" - -[package.extras] -test = ["mock", "pytest", "scripttester"] - -[[package]] -name = "nbclient" -version = "0.10.2" -description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." -optional = false -python-versions = ">=3.9.0" -groups = ["docs"] -files = [ - {file = "nbclient-0.10.2-py3-none-any.whl", hash = "sha256:4ffee11e788b4a27fabeb7955547e4318a5298f34342a4bfd01f2e1faaeadc3d"}, - {file = "nbclient-0.10.2.tar.gz", hash = "sha256:90b7fc6b810630db87a6d0c2250b1f0ab4cf4d3c27a299b0cde78a4ed3fd9193"}, -] - -[package.dependencies] -jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -nbformat = ">=5.1" -traitlets = ">=5.4" - -[package.extras] -dev = ["pre-commit"] -docs = ["autodoc-traits", "flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "mock", "moto", "myst-parser", "nbconvert (>=7.1.0)", "pytest (>=7.0,<8)", "pytest-asyncio", "pytest-cov (>=4.0)", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling", "testpath", "xmltodict"] -test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.1.0)", "pytest (>=7.0,<8)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] - -[[package]] -name = "nbconvert" -version = "7.17.1" -description = "Convert Jupyter Notebooks (.ipynb files) to other formats." -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "nbconvert-7.17.1-py3-none-any.whl", hash = "sha256:aa85c087b435e7bf1ffd03319f658e285f2b89eccab33bc1ba7025495ab3e7c8"}, - {file = "nbconvert-7.17.1.tar.gz", hash = "sha256:34d0d0a7e73ce3cbab6c5aae8f4f468797280b01fd8bd2ca746da8569eddd7d2"}, -] - -[package.dependencies] -beautifulsoup4 = "*" -bleach = {version = "!=5.0.0", extras = ["css"]} -defusedxml = "*" -jinja2 = ">=3.0" -jupyter-core = ">=4.7" -jupyterlab-pygments = "*" -markupsafe = ">=2.0" -mistune = ">=2.0.3,<4" -nbclient = ">=0.5.0" -nbformat = ">=5.7" -packaging = "*" -pandocfilters = ">=1.4.1" -pygments = ">=2.4.1" -traitlets = ">=5.1" - -[package.extras] -all = ["flaky", "intersphinx-registry", "ipykernel", "ipython", "ipywidgets (>=7.5)", "myst-parser", "nbsphinx (>=0.2.12)", "playwright", "pydata-sphinx-theme", "pyqtwebengine (>=5.15)", "pytest (>=7)", "sphinx (>=5.0.2)", "sphinxcontrib-spelling", "tornado (>=6.1)"] -docs = ["intersphinx-registry", "ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (>=5.0.2)", "sphinxcontrib-spelling"] -qtpdf = ["pyqtwebengine (>=5.15)"] -qtpng = ["pyqtwebengine (>=5.15)"] -serve = ["tornado (>=6.1)"] -test = ["flaky", "ipykernel", "ipywidgets (>=7.5)", "pytest (>=7)"] -webpdf = ["playwright"] - -[[package]] -name = "nbformat" -version = "5.10.4" -description = "The Jupyter Notebook format" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b"}, - {file = "nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a"}, -] - -[package.dependencies] -fastjsonschema = ">=2.15" -jsonschema = ">=2.6" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -traitlets = ">=5.1" - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["pep440", "pre-commit", "pytest", "testpath"] - -[[package]] -name = "nest-asyncio" -version = "1.6.0" -description = "Patch asyncio to allow nested event loops" -optional = false -python-versions = ">=3.5" -groups = ["docs"] -files = [ - {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, - {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, -] - -[[package]] -name = "networkx" -version = "3.6.1" -description = "Python package for creating and manipulating graphs and networks" -optional = false -python-versions = "!=3.14.1,>=3.11" -groups = ["main"] -files = [ - {file = "networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762"}, - {file = "networkx-3.6.1.tar.gz", hash = "sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509"}, -] - -[package.extras] -benchmarking = ["asv", "virtualenv"] -default = ["matplotlib (>=3.8)", "numpy (>=1.25)", "pandas (>=2.0)", "scipy (>=1.11.2)"] -developer = ["mypy (>=1.15)", "pre-commit (>=4.1)"] -doc = ["intersphinx-registry", "myst-nb (>=1.1)", "numpydoc (>=1.8.0)", "pillow (>=10)", "pydata-sphinx-theme (>=0.16)", "sphinx (>=8.0)", "sphinx-gallery (>=0.18)", "texext (>=0.6.7)"] -example = ["cairocffi (>=1.7)", "contextily (>=1.6)", "igraph (>=0.11)", "iplotx (>=0.9.0)", "momepy (>=0.7.2)", "osmnx (>=2.0.0)", "scikit-learn (>=1.5)", "seaborn (>=0.13)"] -extra = ["lxml (>=4.6)", "pydot (>=3.0.1)", "pygraphviz (>=1.14)", "sympy (>=1.10)"] -release = ["build (>=0.10)", "changelist (==0.5)", "twine (>=4.0)", "wheel (>=0.40)"] -test = ["pytest (>=7.2)", "pytest-cov (>=4.0)", "pytest-xdist (>=3.0)"] -test-extras = ["pytest-mpl", "pytest-randomly"] - -[[package]] -name = "nodeenv" -version = "1.9.1" -description = "Node.js virtual environment builder" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["dev"] -files = [ - {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, - {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, -] - -[[package]] -name = "numpy" -version = "2.3.5" -description = "Fundamental package for array computing in Python" -optional = false -python-versions = ">=3.11" -groups = ["main", "docs"] -files = [ - {file = "numpy-2.3.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:de5672f4a7b200c15a4127042170a694d4df43c992948f5e1af57f0174beed10"}, - {file = "numpy-2.3.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:acfd89508504a19ed06ef963ad544ec6664518c863436306153e13e94605c218"}, - {file = "numpy-2.3.5-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:ffe22d2b05504f786c867c8395de703937f934272eb67586817b46188b4ded6d"}, - {file = "numpy-2.3.5-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:872a5cf366aec6bb1147336480fef14c9164b154aeb6542327de4970282cd2f5"}, - {file = "numpy-2.3.5-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3095bdb8dd297e5920b010e96134ed91d852d81d490e787beca7e35ae1d89cf7"}, - {file = "numpy-2.3.5-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8cba086a43d54ca804ce711b2a940b16e452807acebe7852ff327f1ecd49b0d4"}, - {file = "numpy-2.3.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6cf9b429b21df6b99f4dee7a1218b8b7ffbbe7df8764dc0bd60ce8a0708fed1e"}, - {file = "numpy-2.3.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:396084a36abdb603546b119d96528c2f6263921c50df3c8fd7cb28873a237748"}, - {file = "numpy-2.3.5-cp311-cp311-win32.whl", hash = "sha256:b0c7088a73aef3d687c4deef8452a3ac7c1be4e29ed8bf3b366c8111128ac60c"}, - {file = "numpy-2.3.5-cp311-cp311-win_amd64.whl", hash = "sha256:a414504bef8945eae5f2d7cb7be2d4af77c5d1cb5e20b296c2c25b61dff2900c"}, - {file = "numpy-2.3.5-cp311-cp311-win_arm64.whl", hash = "sha256:0cd00b7b36e35398fa2d16af7b907b65304ef8bb4817a550e06e5012929830fa"}, - {file = "numpy-2.3.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:74ae7b798248fe62021dbf3c914245ad45d1a6b0cb4a29ecb4b31d0bfbc4cc3e"}, - {file = "numpy-2.3.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee3888d9ff7c14604052b2ca5535a30216aa0a58e948cdd3eeb8d3415f638769"}, - {file = "numpy-2.3.5-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:612a95a17655e213502f60cfb9bf9408efdc9eb1d5f50535cc6eb365d11b42b5"}, - {file = "numpy-2.3.5-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3101e5177d114a593d79dd79658650fe28b5a0d8abeb8ce6f437c0e6df5be1a4"}, - {file = "numpy-2.3.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b973c57ff8e184109db042c842423ff4f60446239bd585a5131cc47f06f789d"}, - {file = "numpy-2.3.5-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0d8163f43acde9a73c2a33605353a4f1bc4798745a8b1d73183b28e5b435ae28"}, - {file = "numpy-2.3.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:51c1e14eb1e154ebd80e860722f9e6ed6ec89714ad2db2d3aa33c31d7c12179b"}, - {file = "numpy-2.3.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b46b4ec24f7293f23adcd2d146960559aaf8020213de8ad1909dba6c013bf89c"}, - {file = "numpy-2.3.5-cp312-cp312-win32.whl", hash = "sha256:3997b5b3c9a771e157f9aae01dd579ee35ad7109be18db0e85dbdbe1de06e952"}, - {file = "numpy-2.3.5-cp312-cp312-win_amd64.whl", hash = "sha256:86945f2ee6d10cdfd67bcb4069c1662dd711f7e2a4343db5cecec06b87cf31aa"}, - {file = "numpy-2.3.5-cp312-cp312-win_arm64.whl", hash = "sha256:f28620fe26bee16243be2b7b874da327312240a7cdc38b769a697578d2100013"}, - {file = "numpy-2.3.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d0f23b44f57077c1ede8c5f26b30f706498b4862d3ff0a7298b8411dd2f043ff"}, - {file = "numpy-2.3.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa5bc7c5d59d831d9773d1170acac7893ce3a5e130540605770ade83280e7188"}, - {file = "numpy-2.3.5-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:ccc933afd4d20aad3c00bcef049cb40049f7f196e0397f1109dba6fed63267b0"}, - {file = "numpy-2.3.5-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:afaffc4393205524af9dfa400fa250143a6c3bc646c08c9f5e25a9f4b4d6a903"}, - {file = "numpy-2.3.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c75442b2209b8470d6d5d8b1c25714270686f14c749028d2199c54e29f20b4d"}, - {file = "numpy-2.3.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11e06aa0af8c0f05104d56450d6093ee639e15f24ecf62d417329d06e522e017"}, - {file = "numpy-2.3.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed89927b86296067b4f81f108a2271d8926467a8868e554eaf370fc27fa3ccaf"}, - {file = "numpy-2.3.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51c55fe3451421f3a6ef9a9c1439e82101c57a2c9eab9feb196a62b1a10b58ce"}, - {file = "numpy-2.3.5-cp313-cp313-win32.whl", hash = "sha256:1978155dd49972084bd6ef388d66ab70f0c323ddee6f693d539376498720fb7e"}, - {file = "numpy-2.3.5-cp313-cp313-win_amd64.whl", hash = "sha256:00dc4e846108a382c5869e77c6ed514394bdeb3403461d25a829711041217d5b"}, - {file = "numpy-2.3.5-cp313-cp313-win_arm64.whl", hash = "sha256:0472f11f6ec23a74a906a00b48a4dcf3849209696dff7c189714511268d103ae"}, - {file = "numpy-2.3.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:414802f3b97f3c1eef41e530aaba3b3c1620649871d8cb38c6eaff034c2e16bd"}, - {file = "numpy-2.3.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5ee6609ac3604fa7780e30a03e5e241a7956f8e2fcfe547d51e3afa5247ac47f"}, - {file = "numpy-2.3.5-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:86d835afea1eaa143012a2d7a3f45a3adce2d7adc8b4961f0b362214d800846a"}, - {file = "numpy-2.3.5-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:30bc11310e8153ca664b14c5f1b73e94bd0503681fcf136a163de856f3a50139"}, - {file = "numpy-2.3.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1062fde1dcf469571705945b0f221b73928f34a20c904ffb45db101907c3454e"}, - {file = "numpy-2.3.5-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce581db493ea1a96c0556360ede6607496e8bf9b3a8efa66e06477267bc831e9"}, - {file = "numpy-2.3.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:cc8920d2ec5fa99875b670bb86ddeb21e295cb07aa331810d9e486e0b969d946"}, - {file = "numpy-2.3.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9ee2197ef8c4f0dfe405d835f3b6a14f5fee7782b5de51ba06fb65fc9b36e9f1"}, - {file = "numpy-2.3.5-cp313-cp313t-win32.whl", hash = "sha256:70b37199913c1bd300ff6e2693316c6f869c7ee16378faf10e4f5e3275b299c3"}, - {file = "numpy-2.3.5-cp313-cp313t-win_amd64.whl", hash = "sha256:b501b5fa195cc9e24fe102f21ec0a44dffc231d2af79950b451e0d99cea02234"}, - {file = "numpy-2.3.5-cp313-cp313t-win_arm64.whl", hash = "sha256:a80afd79f45f3c4a7d341f13acbe058d1ca8ac017c165d3fa0d3de6bc1a079d7"}, - {file = "numpy-2.3.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:bf06bc2af43fa8d32d30fae16ad965663e966b1a3202ed407b84c989c3221e82"}, - {file = "numpy-2.3.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:052e8c42e0c49d2575621c158934920524f6c5da05a1d3b9bab5d8e259e045f0"}, - {file = "numpy-2.3.5-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:1ed1ec893cff7040a02c8aa1c8611b94d395590d553f6b53629a4461dc7f7b63"}, - {file = "numpy-2.3.5-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:2dcd0808a421a482a080f89859a18beb0b3d1e905b81e617a188bd80422d62e9"}, - {file = "numpy-2.3.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:727fd05b57df37dc0bcf1a27767a3d9a78cbbc92822445f32cc3436ba797337b"}, - {file = "numpy-2.3.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fffe29a1ef00883599d1dc2c51aa2e5d80afe49523c261a74933df395c15c520"}, - {file = "numpy-2.3.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f7f0e05112916223d3f438f293abf0727e1181b5983f413dfa2fefc4098245c"}, - {file = "numpy-2.3.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2e2eb32ddb9ccb817d620ac1d8dae7c3f641c1e5f55f531a33e8ab97960a75b8"}, - {file = "numpy-2.3.5-cp314-cp314-win32.whl", hash = "sha256:66f85ce62c70b843bab1fb14a05d5737741e74e28c7b8b5a064de10142fad248"}, - {file = "numpy-2.3.5-cp314-cp314-win_amd64.whl", hash = "sha256:e6a0bc88393d65807d751a614207b7129a310ca4fe76a74e5c7da5fa5671417e"}, - {file = "numpy-2.3.5-cp314-cp314-win_arm64.whl", hash = "sha256:aeffcab3d4b43712bb7a60b65f6044d444e75e563ff6180af8f98dd4b905dfd2"}, - {file = "numpy-2.3.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17531366a2e3a9e30762c000f2c43a9aaa05728712e25c11ce1dbe700c53ad41"}, - {file = "numpy-2.3.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d21644de1b609825ede2f48be98dfde4656aefc713654eeee280e37cadc4e0ad"}, - {file = "numpy-2.3.5-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:c804e3a5aba5460c73955c955bdbd5c08c354954e9270a2c1565f62e866bdc39"}, - {file = "numpy-2.3.5-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:cc0a57f895b96ec78969c34f682c602bf8da1a0270b09bc65673df2e7638ec20"}, - {file = "numpy-2.3.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:900218e456384ea676e24ea6a0417f030a3b07306d29d7ad843957b40a9d8d52"}, - {file = "numpy-2.3.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09a1bea522b25109bf8e6f3027bd810f7c1085c64a0c7ce050c1676ad0ba010b"}, - {file = "numpy-2.3.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04822c00b5fd0323c8166d66c701dc31b7fbd252c100acd708c48f763968d6a3"}, - {file = "numpy-2.3.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d6889ec4ec662a1a37eb4b4fb26b6100841804dac55bd9df579e326cdc146227"}, - {file = "numpy-2.3.5-cp314-cp314t-win32.whl", hash = "sha256:93eebbcf1aafdf7e2ddd44c2923e2672e1010bddc014138b229e49725b4d6be5"}, - {file = "numpy-2.3.5-cp314-cp314t-win_amd64.whl", hash = "sha256:c8a9958e88b65c3b27e22ca2a076311636850b612d6bbfb76e8d156aacde2aaf"}, - {file = "numpy-2.3.5-cp314-cp314t-win_arm64.whl", hash = "sha256:6203fdf9f3dc5bdaed7319ad8698e685c7a3be10819f41d32a0723e611733b42"}, - {file = "numpy-2.3.5-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f0963b55cdd70fad460fa4c1341f12f976bb26cb66021a5580329bd498988310"}, - {file = "numpy-2.3.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f4255143f5160d0de972d28c8f9665d882b5f61309d8362fdd3e103cf7bf010c"}, - {file = "numpy-2.3.5-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:a4b9159734b326535f4dd01d947f919c6eefd2d9827466a696c44ced82dfbc18"}, - {file = "numpy-2.3.5-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:2feae0d2c91d46e59fcd62784a3a83b3fb677fead592ce51b5a6fbb4f95965ff"}, - {file = "numpy-2.3.5-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ffac52f28a7849ad7576293c0cb7b9f08304e8f7d738a8cb8a90ec4c55a998eb"}, - {file = "numpy-2.3.5-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:63c0e9e7eea69588479ebf4a8a270d5ac22763cc5854e9a7eae952a3908103f7"}, - {file = "numpy-2.3.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f16417ec91f12f814b10bafe79ef77e70113a2f5f7018640e7425ff979253425"}, - {file = "numpy-2.3.5.tar.gz", hash = "sha256:784db1dcdab56bf0517743e746dfb0f885fc68d948aba86eeec2cba234bdf1c0"}, -] - -[[package]] -name = "numpydoc" -version = "1.10.0" -description = "Sphinx extension to support docstrings in Numpy format" -optional = false -python-versions = ">=3.10" -groups = ["docs"] -files = [ - {file = "numpydoc-1.10.0-py3-none-any.whl", hash = "sha256:3149da9874af890bcc2a82ef7aae5484e5aa81cb2778f08e3c307ba6d963721b"}, - {file = "numpydoc-1.10.0.tar.gz", hash = "sha256:3f7970f6eee30912260a6b31ac72bba2432830cd6722569ec17ee8d3ef5ffa01"}, -] - -[package.dependencies] -sphinx = ">=6" - -[[package]] -name = "packaging" -version = "25.0" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -groups = ["dev", "docs", "test"] -files = [ - {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, - {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, -] - -[[package]] -name = "pandas" -version = "3.0.5" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.11" -groups = ["main"] -files = [ - {file = "pandas-3.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2946e77e4a53cd248cbde631a12f0e51c8324ce354c3eba4d20147c1ad6f4282"}, - {file = "pandas-3.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:71ecc8fb7ed1a7aa4392316b5309a6347e8e7f832f38fd897846b3a1457a9298"}, - {file = "pandas-3.0.5-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b173f5951ff6b8b0ec7675e20dff3c97b7e7a57dfcce387c2d7c5afe87cb7899"}, - {file = "pandas-3.0.5-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2c0cf1dd9b55a22d105fc46c1b489af3bd42264fcba7c66297bf47a9a1d9c78a"}, - {file = "pandas-3.0.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0fac0010c75e4efb6b99e249c183a8993ce0dc95c240f9b120a5e67c727b7928"}, - {file = "pandas-3.0.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:08d24fe11a17dc33bd6e937dc9c665f9cba08fbdc9f657f405713515febe300d"}, - {file = "pandas-3.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:b1261758dfb6cf12c3cff8300e21cefad30e7ec709abb4c24ac7318e6a52462a"}, - {file = "pandas-3.0.5-cp311-cp311-win_arm64.whl", hash = "sha256:679f4e85b30ddb1515458ab1e788d3e260eae369b1f78da7a3aa4cac8ebf4a2a"}, - {file = "pandas-3.0.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fa290c16964d4963fbfbc358928239cf3bd755b20e988ce944877def2f44471d"}, - {file = "pandas-3.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c2e26bb46934b8a2ca0c3de1d3d606fc5f6746584791b2db264d58cf370e08dc"}, - {file = "pandas-3.0.5-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73fa87b08a7ef706f8aafda39ddaccf2a99047bea62d8c88a0361bcafb2237bc"}, - {file = "pandas-3.0.5-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d373ce03ffd84010ed9839fa73672a9c8256990532e158440c0085db7d914b34"}, - {file = "pandas-3.0.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2a29c53d85ea98c5e792c59ef82ee9fbe6ca902c0d0adb6b23f45ef894cd7bf6"}, - {file = "pandas-3.0.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a5ad3b02ed6bc7d7ae9b70804b2c6aa31827489d150f8e623ce82491b82085d7"}, - {file = "pandas-3.0.5-cp312-cp312-pyemscripten_2024_0_wasm32.whl", hash = "sha256:b2acb4650527eec6822c3dadb2b771277b65e7dae7a267d4bccf65fd1bb3fbce"}, - {file = "pandas-3.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:80a611068e8a3ac23f7398c6c14eb46dc974e5cc9997f653e2dcfd1da74edd41"}, - {file = "pandas-3.0.5-cp312-cp312-win_arm64.whl", hash = "sha256:25ff585b972a18ef1fe9ffa3ac6544d9950508aa76832e5147640b6022821e49"}, - {file = "pandas-3.0.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c1c05a767fe8e5b4fe9e1c29806829c582052eaedb9120a3da83ba3f69e24a5b"}, - {file = "pandas-3.0.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b86765f268b56f7e665b93bce9d5df69dee7f99e595cf8fb839483ab315942a3"}, - {file = "pandas-3.0.5-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c597ecf5616b5c420372c1d4d4c00dbbfba7398bea857dcc984347e1ea48417b"}, - {file = "pandas-3.0.5-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4b11c36e218331d0387cbe3a0a5f75162357a1d92d57b2b08a336ff94b19b2be"}, - {file = "pandas-3.0.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cf52e1f61d229496da17dc7ab54acdee627357e7008fd4fecba3d0ba2937fa58"}, - {file = "pandas-3.0.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:db172144bb56422bd157812f3b021eacc255451470b31e2c633c349490a1cfee"}, - {file = "pandas-3.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:0d298e951f23016ce4699951d044ae6418dbc91bf68cefca0f77666fcbb4e5c6"}, - {file = "pandas-3.0.5-cp313-cp313-win_arm64.whl", hash = "sha256:66266d3442a5e8b3c90274c2b8b230bee42dd1c286bc822cc2f9f2c7e12b883e"}, - {file = "pandas-3.0.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2f264fc46911cc8131a7322a16199bbf8e353d27c10bb211f5bd0c814324dc36"}, - {file = "pandas-3.0.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:53730687fcd161883b24e10411c06d6a4c0f2275d2faf3bb2bc25deb4ba8007c"}, - {file = "pandas-3.0.5-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:960d3ebcf249f75206899fcd2c6de53f736b7265759ced0d3e559df0b8b709b0"}, - {file = "pandas-3.0.5-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e94c2c5ca43bd3ca32bf64d32308887b65e5f9bfd8023ea52755107a999f93b"}, - {file = "pandas-3.0.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e819dd5f62966b481a8cb649d3299ebd886a1ea91ed5a99bf7ce77c98d18ab94"}, - {file = "pandas-3.0.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3c5ed2e7c06e91d340dfd091d7934f9bc82e4a36b95f647f090b9d1c9ac649da"}, - {file = "pandas-3.0.5-cp314-cp314-win_amd64.whl", hash = "sha256:cd8f7c6dc98527058ee6264219343f5392240a6f1bfa654fc5d79023020d0c92"}, - {file = "pandas-3.0.5-cp314-cp314-win_arm64.whl", hash = "sha256:5183427f5a8156d480f30333777bc978be93650a49a7c01db26adffe95b31e85"}, - {file = "pandas-3.0.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:303da736987d481074ca720ada325f8bd80c64ebc2d45ed79b29df3aaa4a26ca"}, - {file = "pandas-3.0.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3b2801bbb049d0136f6c213eae02b5fca969384fc2064dd728d8620552aa49da"}, - {file = "pandas-3.0.5-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cce3a9d11d2b1f82c69a27ec1f4948a170e2c403c4bbfa8cca62e3fdebe2ef3a"}, - {file = "pandas-3.0.5-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef01af4d8dc6cd2c8d6c7736f149574ef93fe043811eeb5e445f2647154b5040"}, - {file = "pandas-3.0.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e2759e890db96dfcffdbd9b86c3c2cb6afaf58def482820317e06163ec1066cd"}, - {file = "pandas-3.0.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b58b1b39d46a5862e3fb18f50d1a201398619d16a0f9f73f57eea5583cf0e63c"}, - {file = "pandas-3.0.5-cp314-cp314t-win_amd64.whl", hash = "sha256:1c10461f6eeb35d8f05b6184c65c8b9991663b66c46b1d559b682cb34ae7c6ea"}, - {file = "pandas-3.0.5-cp314-cp314t-win_arm64.whl", hash = "sha256:3c5015fd1730fbf883647e88068176c839c102cea883ba1769a6f4593bfc1f8c"}, - {file = "pandas-3.0.5.tar.gz", hash = "sha256:dca3734d6ab7c906e6730f0788b0a1dbb9f2467731f9711f77995c8e9d62d712"}, -] - -[package.dependencies] -numpy = {version = ">=1.26.0", markers = "python_version < \"3.14\""} -python-dateutil = ">=2.8.2" -tzdata = {version = "*", markers = "sys_platform == \"win32\" or sys_platform == \"emscripten\""} - -[package.extras] -all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.36)", "adbc-driver-postgresql (>=1.2.0)", "adbc-driver-sqlite (>=1.2.0)", "beautifulsoup4 (>=4.12.3)", "bottleneck (>=1.4.2)", "fastparquet (>=2024.11.0)", "fsspec (>=2024.10.0)", "gcsfs (>=2024.10.0)", "html5lib (>=1.1)", "hypothesis (>=6.116.0)", "jinja2 (>=3.1.5)", "lxml (>=5.3.0)", "matplotlib (>=3.9.3)", "numba (>=0.60.0)", "numexpr (>=2.10.2)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.5)", "psycopg2 (>=2.9.10)", "pyarrow (>=13.0.0)", "pyiceberg (>=0.8.1)", "pymysql (>=1.1.1)", "pyreadstat (>=1.2.8)", "pytest (>=8.3.4)", "pytest-xdist (>=3.6.1)", "python-calamine (>=0.3.0)", "pytz (>=2020.1)", "pyxlsb (>=1.0.10)", "qtpy (>=2.4.2)", "s3fs (>=2024.10.0)", "scipy (>=1.14.1)", "tables (>=3.10.1)", "tabulate (>=0.9.0)", "xarray (>=2024.10.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.2.0)", "zstandard (>=0.23.0)"] -aws = ["s3fs (>=2024.10.0)"] -clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.4.2)"] -compression = ["zstandard (>=0.23.0)"] -computation = ["scipy (>=1.14.1)", "xarray (>=2024.10.0)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.5)", "python-calamine (>=0.3.0)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.2.0)"] -feather = ["pyarrow (>=13.0.0)"] -fss = ["fsspec (>=2024.10.0)"] -gcp = ["gcsfs (>=2024.10.0)"] -hdf5 = ["tables (>=3.10.1)"] -html = ["beautifulsoup4 (>=4.12.3)", "html5lib (>=1.1)", "lxml (>=5.3.0)"] -iceberg = ["pyiceberg (>=0.8.1)"] -mysql = ["SQLAlchemy (>=2.0.36)", "pymysql (>=1.1.1)"] -output-formatting = ["jinja2 (>=3.1.5)", "tabulate (>=0.9.0)"] -parquet = ["pyarrow (>=13.0.0)"] -performance = ["bottleneck (>=1.4.2)", "numba (>=0.60.0)", "numexpr (>=2.10.2)"] -plot = ["matplotlib (>=3.9.3)"] -postgresql = ["SQLAlchemy (>=2.0.36)", "adbc-driver-postgresql (>=1.2.0)", "psycopg2 (>=2.9.10)"] -pyarrow = ["pyarrow (>=13.0.0)"] -spss = ["pyreadstat (>=1.2.8)"] -sql-other = ["SQLAlchemy (>=2.0.36)", "adbc-driver-postgresql (>=1.2.0)", "adbc-driver-sqlite (>=1.2.0)"] -test = ["hypothesis (>=6.116.0)", "pytest (>=8.3.4,<9.1)", "pytest-xdist (>=3.6.1)"] -timezone = ["pytz (>=2020.1)"] -xml = ["lxml (>=5.3.0)"] - -[[package]] -name = "pandocfilters" -version = "1.5.1" -description = "Utilities for writing pandoc filters in python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -groups = ["docs"] -files = [ - {file = "pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc"}, - {file = "pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e"}, -] - -[[package]] -name = "parso" -version = "0.8.5" -description = "A Python Parser" -optional = false -python-versions = ">=3.6" -groups = ["docs"] -files = [ - {file = "parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887"}, - {file = "parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a"}, -] - -[package.extras] -qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["docopt", "pytest"] - -[[package]] -name = "pathspec" -version = "1.1.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189"}, - {file = "pathspec-1.1.1.tar.gz", hash = "sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a"}, -] - -[package.extras] -hyperscan = ["hyperscan (>=0.7)"] -optional = ["typing-extensions (>=4)"] -re2 = ["google-re2 (>=1.1)"] - -[[package]] -name = "pexpect" -version = "4.9.0" -description = "Pexpect allows easy control of interactive console applications." -optional = false -python-versions = "*" -groups = ["docs"] -markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\"" -files = [ - {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, - {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, -] - -[package.dependencies] -ptyprocess = ">=0.5" - -[[package]] -name = "pillow" -version = "12.3.0" -description = "Python Imaging Library (fork)" -optional = false -python-versions = ">=3.10" -groups = ["docs"] -files = [ - {file = "pillow-12.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6c0016e7b354317c4e9e525b937ac8596c38d2d232b419529b9cd7a1cd46e39a"}, - {file = "pillow-12.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bcc33feacfaefce60c12fd500a277533bdc02b10a19f7f6d348763d8140bbba7"}, - {file = "pillow-12.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5594fc43d548a7ed94949d139aa1341b270f1863f11cfd37f5a6c8b778a6b67f"}, - {file = "pillow-12.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0606c8bf2cdefea14a43530f7657cbbb7ecf1c4222512492ef4a4434a9501ec"}, - {file = "pillow-12.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:85f998ea1848bc6757289e739cfbdda3a04adfd58b02fc018ce54d754a5ce468"}, - {file = "pillow-12.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:25b9b82bb22e6e2b3cd07b39c68b7b862001226cb3dff7130d1cb914121b39ed"}, - {file = "pillow-12.3.0-cp310-cp310-win32.whl", hash = "sha256:37dc8f7bbb66efe481bb60defacef820c950c24713fb44962ed6aa2a50966de1"}, - {file = "pillow-12.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:300557495eb45ebb8aec96c2da9c4be642fbf7cd937278b4013ba894ea8eb0eb"}, - {file = "pillow-12.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:514435a37670e3e5e08f3945b68718b6ed329bb84367777e16f9f4dfe1e61a0f"}, - {file = "pillow-12.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:00808c5e14ef63ac5161091d242999076604ff74b883423a11e5d7bbb38bf756"}, - {file = "pillow-12.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37d6d0a00072fd2948eb22bce7e1475f34569d90c87c59f7a2ec59541b77f7a6"}, - {file = "pillow-12.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bcb46e2f9feff8d06323983bd83ed00c201fdcab3d74973e7072a889b3979fcd"}, - {file = "pillow-12.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23d27a3e0307ec2244cc51e7287b919aa68d097504ebe19df4e76a98a3eea5bd"}, - {file = "pillow-12.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4f883547d4b7f0495ebe7056b0cc2aea76094e7a4abc8e933540f3271df27d9c"}, - {file = "pillow-12.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:236ff70b9312fb68943c703aa842ca6a758abfa45ac187a5e7c1452e96ef72b5"}, - {file = "pillow-12.3.0-cp311-cp311-win32.whl", hash = "sha256:10e41f0fbf1eec8cfd234b8fe17a4caac7c9d0db4c204d3c173a8f9f6ef3232b"}, - {file = "pillow-12.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8e95e1385e4998ae9694eeaa4730ba5457ff61185b3a55e2e7bea0880aef452a"}, - {file = "pillow-12.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:ebaea975e03d3141d9d3a507df75c9b3ec90fa9d2ffd07567b3a978d9d790b26"}, - {file = "pillow-12.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ba09209fbe443b4acccebe845d8a138b89a8f4fbaeedd44953490b5315d5e965"}, - {file = "pillow-12.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffd0c5368496f41b0944be820fcb7a838aa6e623d250b01acf2643939c3f99d7"}, - {file = "pillow-12.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9c7f76c0673154f044e9d78c8655fb4213f6ca31a836df48b40fe5d187717b9"}, - {file = "pillow-12.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:78cb2c6865a35ab8ff8b75fd122f6033b92a62c82801110e48ddd6c936a45d91"}, - {file = "pillow-12.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e491916b378fba47242221bb9ead245211b70d504f495d105d17b14a24b4907c"}, - {file = "pillow-12.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0dd2064cbc55aaec028ef5fbb60fa47bb6c3e7918e07ff17935284b227a9d2df"}, - {file = "pillow-12.3.0-cp312-cp312-win32.whl", hash = "sha256:dbce0b29841537a2fa4a214c2bbf14de3587c9680caa9b4e217568472490b28f"}, - {file = "pillow-12.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a2b55dd6b2a4c4b7d87ffa56bdb33fdc5fdb9a462173861a7bc097f17d91cb09"}, - {file = "pillow-12.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:331b624368d4f1d069149002f25f44bc61c8919ce8ddb3c45bdad8f6e2d89510"}, - {file = "pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:21900ce7ba264168cd50defae43cd75d25c833ad4ad6e73ffc5596d12e25ac89"}, - {file = "pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:4e8c2a84d977f50b9daed6eeaf3baef67d00d5d74d932288f02cb94518ee3ace"}, - {file = "pillow-12.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:ae26d61dfa7a47befdc7572b521024e8745f3d809bd95ca9505a7bba9ef849ec"}, - {file = "pillow-12.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7a743ff716f746fc19a9557f60dab1600d4613255f8a7aeb3cdde4db7eb15a66"}, - {file = "pillow-12.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d69141514cc30b774ceea5e3ed3a6635c8d8a96edf664689b890f4089111fb35"}, - {file = "pillow-12.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f7401aebd7f581d7f83a439d87d474999317ee099218e5ad25d125290990ba65"}, - {file = "pillow-12.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0847a763afefb695bc912d7c131e7e0632d4edc1d8698f58ddabec8e46b8b6d3"}, - {file = "pillow-12.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:571b9fcb07b97ef3a492028fb3d2dc0993ca23a06138b0315286566d29ef718a"}, - {file = "pillow-12.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:756c768d0c9c2955feb7a56c37ea24aea2e369f8d36a88da270b6a9f19e62b5e"}, - {file = "pillow-12.3.0-cp313-cp313-win32.whl", hash = "sha256:a876864214e136f0eb367788dbd7df045f4806801518e2cfe9e13229cfe06d8f"}, - {file = "pillow-12.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:1cca606cd25738df4ed873d5ad46bbdb3d83b5cbca291f6b4ff13a4df6b0bbe8"}, - {file = "pillow-12.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:b629de27fda84b42cde7edef0d85f13b958b47f6e9bbcbba9b673c562a89bd8b"}, - {file = "pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:9cf95fe4d0f84c82d282745d9bb08ad9f926efa00be4697e767b814ce40d4330"}, - {file = "pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8728f216dcdb6e6d555cf971cb34076139ad74b31fc2c14da4fafc741c5f6217"}, - {file = "pillow-12.3.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:a45650e8ce7fafffd731db8550230db6b0d306d181a90b67d3e6bca2f1990930"}, - {file = "pillow-12.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ba54cfebe86920a559a7c4d6b9050791c20513650a1952ebe3368c7dc70306f8"}, - {file = "pillow-12.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e158cb00350dc278f3b91551101aa7d12415a66ebf2c91d8d5ac14e56ddd3ad0"}, - {file = "pillow-12.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9aeb04d6aef139de265b29683e119b638208f88cf73cdd1658aa07221165321"}, - {file = "pillow-12.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:251bf95b67017e27b13d82f5b326234ca62d70f9cf4c2b9032de2358a3b12c7b"}, - {file = "pillow-12.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fe3cca2e4e8a592be0f269a1ca4835c25199d9f3ce815c8491048f785b0a0198"}, - {file = "pillow-12.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:23aceaa007d6172b02c277f0cd359c79492bbb14f7072b4ede9fbcaf20648130"}, - {file = "pillow-12.3.0-cp314-cp314-win32.whl", hash = "sha256:af8d94b0db561cf68b88a267c5c44b49e134f525d0dc2cb7ed413a66bc23559a"}, - {file = "pillow-12.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:fdafc9cce40277e0f7a0feabce0ee50dd2fa1800f3b38015e51296b5e814048d"}, - {file = "pillow-12.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:e91206ee562682b51b98ef4b26a6ef48fd84e15fd4c4bc5ec768eb641d206838"}, - {file = "pillow-12.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:164b31cd1a0490ab6efae01aa5df49da7061be0af1b30e035b6e9a1bfe34ee6e"}, - {file = "pillow-12.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5afb51d599ea772b8365ae807ae557f18bccfe46ab261fd1c2a9ed700fc6eb17"}, - {file = "pillow-12.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3edce1d53195db527e0191f84b71d02022de0540bf43a16ed734ed7537b07385"}, - {file = "pillow-12.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf16ba1b4d0b6b7c8e534936632270cf70eb00dbe09005bc345b2677b726855c"}, - {file = "pillow-12.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:24870b09b224f7ae3c39ed07d10e819d06f8720bc551847b1d623832b5b0e28d"}, - {file = "pillow-12.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:30f2aa603c41533cc25c05acd0da21636e84a315768feb631c937177db558931"}, - {file = "pillow-12.3.0-cp314-cp314t-win32.whl", hash = "sha256:4b0a7fe987b14c31ebda6083f74f22b561fd3739bc0ac51e019622e3d72668c7"}, - {file = "pillow-12.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:962864dc93511324d51ddbb5b9f8731bf71675b93ca612a07441896f4688fb8c"}, - {file = "pillow-12.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0740a512dc522224c77d9aa5a8d70d8b7d73fb91f2c21125d8d025d3b8990e45"}, - {file = "pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0feb2e9d6ad6c9e3c06effe9d00f3f1e618a6643273576b016f591e9315a7139"}, - {file = "pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:9e881fca225083806662a5c43d627d215f258ff43c890f831966c7d7ba9c7402"}, - {file = "pillow-12.3.0-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:4998562bf62a445225f22e07c896bb04b35b1b1f2eb6d760584c9c51d7a5f78c"}, - {file = "pillow-12.3.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:dc624f6bc473dacdf7ef7eb8678d0d08edf15cd94fad6ae5c7d6cc67a4e4902f"}, - {file = "pillow-12.3.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:71d6097b330eea8fd15097780c8e89cb1a8ce7838669f48c5bacd6f663dd4701"}, - {file = "pillow-12.3.0-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:28ce87c5ab450a9dd970b52e5aca5fe63ed432d18a2eaddd1979a00a1ba24ace"}, - {file = "pillow-12.3.0-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6b02afb9b97f65fbca5f31db6a2a3ba21aa93030225f150fa3f249717e938fb4"}, - {file = "pillow-12.3.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:1182d52bc2d5e5d7d0949503aa7e36d12f42205dc287e4883f407b1988820d39"}, - {file = "pillow-12.3.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e795b7eb908249c4e43c7c99fac7c2c75dab0c43566e37db472a355f63693d71"}, - {file = "pillow-12.3.0-cp315-cp315-win32.whl", hash = "sha256:57b3d78c95ba9059768b10e28b813002261d3f3dfc55cc48b0c988f625175827"}, - {file = "pillow-12.3.0-cp315-cp315-win_amd64.whl", hash = "sha256:fa4ecea169a355be7a3ade2c783e2ed12f0e40d2c5621cda8b3297faf7fbb9f5"}, - {file = "pillow-12.3.0-cp315-cp315-win_arm64.whl", hash = "sha256:877c3f311ff35410f690861c4409e7ccbf0cd2f878e50628a28e5a0bb689e658"}, - {file = "pillow-12.3.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:e9871b1ffbfa9656b60aeee92ed5136a5742696006fa322b29ea3d8da0ecc9cf"}, - {file = "pillow-12.3.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:53aa02d20d10c3d814d536aa4e5ac9b84ca0ff5a88377963b085ad6822f93e64"}, - {file = "pillow-12.3.0-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:446c34dcc4324b084a53b705127dc15717b22c5e140ae0a3c38349d4efec071e"}, - {file = "pillow-12.3.0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf1845d02ad822a369a49f2bb9345b1614744267682e7a03527dc3bf6eea1777"}, - {file = "pillow-12.3.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:186941b6aef820ad110fb01fb06eb925374dc3a21b17e37ec9a53b250c6fe2d1"}, - {file = "pillow-12.3.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:f13c32a3abd6079a66d9526e18dad9b6d280384d49d7c54040cd57b6424041d9"}, - {file = "pillow-12.3.0-cp315-cp315t-win32.whl", hash = "sha256:1657923d2d45afb66526e5b933e5b3052e6bdea196c90d3abb2424e18c77dae8"}, - {file = "pillow-12.3.0-cp315-cp315t-win_amd64.whl", hash = "sha256:8cd2f7bdda092d99c9fc2fb7391354f306d01443d22785d0cbfafa2e2c8bb418"}, - {file = "pillow-12.3.0-cp315-cp315t-win_arm64.whl", hash = "sha256:06ff022112bc9cbf83b60f8e028d94ad87b60621706487e65f673de61610ab59"}, - {file = "pillow-12.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b3c777e849237620b022f7f297dd67705f9f5cf1685f09f02e46f93e92725468"}, - {file = "pillow-12.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:b343699e8308bdc51978310e1c959c584e7869cc8c40780058c87da7781a1e94"}, - {file = "pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbd139c8447d25dd750ab79ee274cc5e1fe80fc56340ab10b18a195e1b6eca3e"}, - {file = "pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e7e480451b9fa137494bccd3a7d69adbe8ac65a87d97be61e11f1b1050a5bac3"}, - {file = "pillow-12.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:04f01d28a6aaff387bf842a13be313df23ba0597a44f1a976c9feb3c6ff4711a"}, - {file = "pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] -fpx = ["olefile"] -mic = ["olefile"] -test-arrow = ["arro3-compute", "arro3-core", "nanoarrow", "pyarrow"] -tests = ["coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "setuptools", "trove-classifiers (>=2024.10.12)"] -xmp = ["defusedxml"] - -[[package]] -name = "platformdirs" -version = "4.5.1" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.10" -groups = ["dev", "docs"] -files = [ - {file = "platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31"}, - {file = "platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda"}, -] - -[package.extras] -docs = ["furo (>=2025.9.25)", "proselint (>=0.14)", "sphinx (>=8.2.3)", "sphinx-autodoc-typehints (>=3.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.4.2)", "pytest-cov (>=7)", "pytest-mock (>=3.15.1)"] -type = ["mypy (>=1.18.2)"] - -[[package]] -name = "pluggy" -version = "1.6.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.9" -groups = ["dev", "test"] -files = [ - {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, - {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["coverage", "pytest", "pytest-benchmark"] - -[[package]] -name = "pre-commit" -version = "4.5.1" -description = "A framework for managing and maintaining multi-language pre-commit hooks." -optional = false -python-versions = ">=3.10" -groups = ["dev"] -files = [ - {file = "pre_commit-4.5.1-py2.py3-none-any.whl", hash = "sha256:3b3afd891e97337708c1674210f8eba659b52a38ea5f822ff142d10786221f77"}, - {file = "pre_commit-4.5.1.tar.gz", hash = "sha256:eb545fcff725875197837263e977ea257a402056661f09dae08e4b149b030a61"}, -] - -[package.dependencies] -cfgv = ">=2.0.0" -identify = ">=1.0.0" -nodeenv = ">=0.11.1" -pyyaml = ">=5.1" -virtualenv = ">=20.10.0" - -[[package]] -name = "prompt-toolkit" -version = "3.0.52" -description = "Library for building powerful interactive command lines in Python" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955"}, - {file = "prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855"}, -] - -[package.dependencies] -wcwidth = "*" - -[[package]] -name = "psutil" -version = "7.1.3" -description = "Cross-platform lib for process and system monitoring." -optional = false -python-versions = ">=3.6" -groups = ["docs"] -files = [ - {file = "psutil-7.1.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0005da714eee687b4b8decd3d6cc7c6db36215c9e74e5ad2264b90c3df7d92dc"}, - {file = "psutil-7.1.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:19644c85dcb987e35eeeaefdc3915d059dac7bd1167cdcdbf27e0ce2df0c08c0"}, - {file = "psutil-7.1.3-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:95ef04cf2e5ba0ab9eaafc4a11eaae91b44f4ef5541acd2ee91d9108d00d59a7"}, - {file = "psutil-7.1.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1068c303be3a72f8e18e412c5b2a8f6d31750fb152f9cb106b54090296c9d251"}, - {file = "psutil-7.1.3-cp313-cp313t-win_amd64.whl", hash = "sha256:18349c5c24b06ac5612c0428ec2a0331c26443d259e2a0144a9b24b4395b58fa"}, - {file = "psutil-7.1.3-cp313-cp313t-win_arm64.whl", hash = "sha256:c525ffa774fe4496282fb0b1187725793de3e7c6b29e41562733cae9ada151ee"}, - {file = "psutil-7.1.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:b403da1df4d6d43973dc004d19cee3b848e998ae3154cc8097d139b77156c353"}, - {file = "psutil-7.1.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ad81425efc5e75da3f39b3e636293360ad8d0b49bed7df824c79764fb4ba9b8b"}, - {file = "psutil-7.1.3-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f33a3702e167783a9213db10ad29650ebf383946e91bc77f28a5eb083496bc9"}, - {file = "psutil-7.1.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fac9cd332c67f4422504297889da5ab7e05fd11e3c4392140f7370f4208ded1f"}, - {file = "psutil-7.1.3-cp314-cp314t-win_amd64.whl", hash = "sha256:3792983e23b69843aea49c8f5b8f115572c5ab64c153bada5270086a2123c7e7"}, - {file = "psutil-7.1.3-cp314-cp314t-win_arm64.whl", hash = "sha256:31d77fcedb7529f27bb3a0472bea9334349f9a04160e8e6e5020f22c59893264"}, - {file = "psutil-7.1.3-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2bdbcd0e58ca14996a42adf3621a6244f1bb2e2e528886959c72cf1e326677ab"}, - {file = "psutil-7.1.3-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:bc31fa00f1fbc3c3802141eede66f3a2d51d89716a194bf2cd6fc68310a19880"}, - {file = "psutil-7.1.3-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3bb428f9f05c1225a558f53e30ccbad9930b11c3fc206836242de1091d3e7dd3"}, - {file = "psutil-7.1.3-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56d974e02ca2c8eb4812c3f76c30e28836fffc311d55d979f1465c1feeb2b68b"}, - {file = "psutil-7.1.3-cp37-abi3-win_amd64.whl", hash = "sha256:f39c2c19fe824b47484b96f9692932248a54c43799a84282cfe58d05a6449efd"}, - {file = "psutil-7.1.3-cp37-abi3-win_arm64.whl", hash = "sha256:bd0d69cee829226a761e92f28140bec9a5ee9d5b4fb4b0cc589068dbfff559b1"}, - {file = "psutil-7.1.3.tar.gz", hash = "sha256:6c86281738d77335af7aec228328e944b30930899ea760ecf33a4dba66be5e74"}, -] - -[package.extras] -dev = ["abi3audit", "black", "check-manifest", "colorama ; os_name == \"nt\"", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pyreadline ; os_name == \"nt\"", "pytest", "pytest-cov", "pytest-instafail", "pytest-subtests", "pytest-xdist", "pywin32 ; os_name == \"nt\" and platform_python_implementation != \"PyPy\"", "requests", "rstcheck", "ruff", "setuptools", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "validate-pyproject[all]", "virtualenv", "vulture", "wheel", "wheel ; os_name == \"nt\" and platform_python_implementation != \"PyPy\"", "wmi ; os_name == \"nt\" and platform_python_implementation != \"PyPy\""] -test = ["pytest", "pytest-instafail", "pytest-subtests", "pytest-xdist", "pywin32 ; os_name == \"nt\" and platform_python_implementation != \"PyPy\"", "setuptools", "wheel ; os_name == \"nt\" and platform_python_implementation != \"PyPy\"", "wmi ; os_name == \"nt\" and platform_python_implementation != \"PyPy\""] - -[[package]] -name = "ptyprocess" -version = "0.7.0" -description = "Run a subprocess in a pseudo terminal" -optional = false -python-versions = "*" -groups = ["docs"] -markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\"" -files = [ - {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, - {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, -] - -[[package]] -name = "pure-eval" -version = "0.2.3" -description = "Safely evaluate AST nodes without side effects" -optional = false -python-versions = "*" -groups = ["docs"] -files = [ - {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, - {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, -] - -[package.extras] -tests = ["pytest"] - -[[package]] -name = "pycparser" -version = "2.23" -description = "C parser in Python" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -markers = "implementation_name == \"pypy\"" -files = [ - {file = "pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934"}, - {file = "pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2"}, -] - -[[package]] -name = "pydata-sphinx-theme" -version = "0.21.0" -description = "Bootstrap-based Sphinx theme from the PyData community" -optional = false -python-versions = ">=3.11" -groups = ["docs"] -files = [ - {file = "pydata_sphinx_theme-0.21.0-py3-none-any.whl", hash = "sha256:d36a754bf9580b01789efa8a01869f2d7c87fa6c543ecbcafb14b6bdd4364f90"}, - {file = "pydata_sphinx_theme-0.21.0.tar.gz", hash = "sha256:dc3f71216ea34725ddad68e505497eab4ba134a88abfb971a7df6b28a35c1997"}, -] - -[package.dependencies] -accessible-pygments = "*" -Babel = "*" -beautifulsoup4 = "*" -docutils = "!=0.17.0" -jinja2 = "*" -pygments = ">=2.7" -requests = "*" -sphinx = ">=8.2,<10" - -[package.extras] -a11y = ["pydata-sphinx-theme[test]"] -dev = ["pandoc", "pre-commit", "pydata-sphinx-theme[doc,test]", "pyyaml", "sphinx-theme-builder[cli]", "tox"] -doc = ["ablog (>=0.11.8)", "astroid (>=3,!=4.0.3)", "colorama", "graphviz", "ipykernel", "ipyleaflet", "ipywidgets", "jupyter_sphinx", "jupyterlite-sphinx", "linkify-it-py", "matplotlib", "myst-parser", "nbsphinx", "numpy", "numpydoc", "pandas", "plotly", "rich", "sphinx-autoapi (==3.6.1)", "sphinx-copybutton", "sphinx-design", "sphinx-favicon (>=1.0.1)", "sphinx-sitemap (<2.7.0)", "sphinx-togglebutton", "sphinxcontrib-mermaid", "sphinxcontrib-youtube (>=1.4.1)", "sphinxext-rediraffe", "xarray"] -i18n = ["Babel", "jinja2"] -test = ["pytest", "pytest-cov", "pytest-playwright", "pytest-regressions", "sphinx[test]", "typing-extensions"] - -[[package]] -name = "pydot" -version = "4.0.1" -description = "Python interface to Graphviz's Dot" -optional = false -python-versions = ">=3.8" -groups = ["main"] -files = [ - {file = "pydot-4.0.1-py3-none-any.whl", hash = "sha256:869c0efadd2708c0be1f916eb669f3d664ca684bc57ffb7ecc08e70d5e93fee6"}, - {file = "pydot-4.0.1.tar.gz", hash = "sha256:c2148f681c4a33e08bf0e26a9e5f8e4099a82e0e2a068098f32ce86577364ad5"}, -] - -[package.dependencies] -pyparsing = ">=3.1.0" - -[package.extras] -dev = ["chardet", "parameterized", "pydot[lint]", "pydot[types]"] -lint = ["ruff"] -release = ["zest.releaser[recommended]"] -tests = ["pydot[dev]", "pytest", "pytest-cov", "pytest-xdist[psutil]", "tox"] -types = ["mypy"] - -[[package]] -name = "pyformlang" -version = "1.0.1" -description = "A python framework for formal grammars" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "pyformlang-1.0.1-py3-none-any.whl", hash = "sha256:ae2d4c2a7ddd56ce84f23e54c522fb03ef433a381d46961442aca6d0850e4f1c"}, - {file = "pyformlang-1.0.1.tar.gz", hash = "sha256:7135f281ab59e77136483a8e7803e1ef692933f903372a2c373d69b7da2aef5f"}, -] - -[package.dependencies] -networkx = "*" -numpy = "*" -pydot = "*" - -[[package]] -name = "pygments" -version = "2.20.0" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.9" -groups = ["dev", "docs", "test"] -files = [ - {file = "pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176"}, - {file = "pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f"}, -] - -[package.extras] -windows-terminal = ["colorama (>=0.4.6)"] - -[[package]] -name = "pyparsing" -version = "3.2.5" -description = "pyparsing - Classes and methods to define and execute parsing grammars" -optional = false -python-versions = ">=3.9" -groups = ["main", "docs"] -files = [ - {file = "pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e"}, - {file = "pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6"}, -] - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - -[[package]] -name = "pytest" -version = "9.0.2" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.10" -groups = ["dev", "test"] -files = [ - {file = "pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b"}, - {file = "pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11"}, -] - -[package.dependencies] -colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} -iniconfig = ">=1.0.1" -packaging = ">=22" -pluggy = ">=1.5,<2" -pygments = ">=2.7.2" - -[package.extras] -dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-cov" -version = "7.0.0" -description = "Pytest plugin for measuring coverage." -optional = false -python-versions = ">=3.9" -groups = ["test"] -files = [ - {file = "pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861"}, - {file = "pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1"}, -] - -[package.dependencies] -coverage = {version = ">=7.10.6", extras = ["toml"]} -pluggy = ">=1.2" -pytest = ">=7" - -[package.extras] -testing = ["process-tests", "pytest-xdist", "virtualenv"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main", "dev", "docs"] -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytokens" -version = "0.4.1" -description = "A Fast, spec compliant Python 3.14+ tokenizer that runs on older Pythons." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "pytokens-0.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a44ed93ea23415c54f3face3b65ef2b844d96aeb3455b8a69b3df6beab6acc5"}, - {file = "pytokens-0.4.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:add8bf86b71a5d9fb5b89f023a80b791e04fba57960aa790cc6125f7f1d39dfe"}, - {file = "pytokens-0.4.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:670d286910b531c7b7e3c0b453fd8156f250adb140146d234a82219459b9640c"}, - {file = "pytokens-0.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4e691d7f5186bd2842c14813f79f8884bb03f5995f0575272009982c5ac6c0f7"}, - {file = "pytokens-0.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:27b83ad28825978742beef057bfe406ad6ed524b2d28c252c5de7b4a6dd48fa2"}, - {file = "pytokens-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d70e77c55ae8380c91c0c18dea05951482e263982911fc7410b1ffd1dadd3440"}, - {file = "pytokens-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a58d057208cb9075c144950d789511220b07636dd2e4708d5645d24de666bdc"}, - {file = "pytokens-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b49750419d300e2b5a3813cf229d4e5a4c728dae470bcc89867a9ad6f25a722d"}, - {file = "pytokens-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9907d61f15bf7261d7e775bd5d7ee4d2930e04424bab1972591918497623a16"}, - {file = "pytokens-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:ee44d0f85b803321710f9239f335aafe16553b39106384cef8e6de40cb4ef2f6"}, - {file = "pytokens-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:140709331e846b728475786df8aeb27d24f48cbcf7bcd449f8de75cae7a45083"}, - {file = "pytokens-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d6c4268598f762bc8e91f5dbf2ab2f61f7b95bdc07953b602db879b3c8c18e1"}, - {file = "pytokens-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24afde1f53d95348b5a0eb19488661147285ca4dd7ed752bbc3e1c6242a304d1"}, - {file = "pytokens-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5ad948d085ed6c16413eb5fec6b3e02fa00dc29a2534f088d3302c47eb59adf9"}, - {file = "pytokens-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:3f901fe783e06e48e8cbdc82d631fca8f118333798193e026a50ce1b3757ea68"}, - {file = "pytokens-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8bdb9d0ce90cbf99c525e75a2fa415144fd570a1ba987380190e8b786bc6ef9b"}, - {file = "pytokens-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5502408cab1cb18e128570f8d598981c68a50d0cbd7c61312a90507cd3a1276f"}, - {file = "pytokens-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29d1d8fb1030af4d231789959f21821ab6325e463f0503a61d204343c9b355d1"}, - {file = "pytokens-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:970b08dd6b86058b6dc07efe9e98414f5102974716232d10f32ff39701e841c4"}, - {file = "pytokens-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:9bd7d7f544d362576be74f9d5901a22f317efc20046efe2034dced238cbbfe78"}, - {file = "pytokens-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4a14d5f5fc78ce85e426aa159489e2d5961acf0e47575e08f35584009178e321"}, - {file = "pytokens-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f50fd18543be72da51dd505e2ed20d2228c74e0464e4262e4899797803d7fa"}, - {file = "pytokens-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc74c035f9bfca0255c1af77ddd2d6ae8419012805453e4b0e7513e17904545d"}, - {file = "pytokens-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f66a6bbe741bd431f6d741e617e0f39ec7257ca1f89089593479347cc4d13324"}, - {file = "pytokens-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:b35d7e5ad269804f6697727702da3c517bb8a5228afa450ab0fa787732055fc9"}, - {file = "pytokens-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8fcb9ba3709ff77e77f1c7022ff11d13553f3c30299a9fe246a166903e9091eb"}, - {file = "pytokens-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:79fc6b8699564e1f9b521582c35435f1bd32dd06822322ec44afdeba666d8cb3"}, - {file = "pytokens-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d31b97b3de0f61571a124a00ffe9a81fb9939146c122c11060725bd5aea79975"}, - {file = "pytokens-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:967cf6e3fd4adf7de8fc73cd3043754ae79c36475c1c11d514fc72cf5490094a"}, - {file = "pytokens-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:584c80c24b078eec1e227079d56dc22ff755e0ba8654d8383b2c549107528918"}, - {file = "pytokens-0.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:da5baeaf7116dced9c6bb76dc31ba04a2dc3695f3d9f74741d7910122b456edc"}, - {file = "pytokens-0.4.1-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11edda0942da80ff58c4408407616a310adecae1ddd22eef8c692fe266fa5009"}, - {file = "pytokens-0.4.1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0fc71786e629cef478cbf29d7ea1923299181d0699dbe7c3c0f4a583811d9fc1"}, - {file = "pytokens-0.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:dcafc12c30dbaf1e2af0490978352e0c4041a7cde31f4f81435c2a5e8b9cabb6"}, - {file = "pytokens-0.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:42f144f3aafa5d92bad964d471a581651e28b24434d184871bd02e3a0d956037"}, - {file = "pytokens-0.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:34bcc734bd2f2d5fe3b34e7b3c0116bfb2397f2d9666139988e7a3eb5f7400e3"}, - {file = "pytokens-0.4.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:941d4343bf27b605e9213b26bfa1c4bf197c9c599a9627eb7305b0defcfe40c1"}, - {file = "pytokens-0.4.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3ad72b851e781478366288743198101e5eb34a414f1d5627cdd585ca3b25f1db"}, - {file = "pytokens-0.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:682fa37ff4d8e95f7df6fe6fe6a431e8ed8e788023c6bcc0f0880a12eab80ad1"}, - {file = "pytokens-0.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:30f51edd9bb7f85c748979384165601d028b84f7bd13fe14d3e065304093916a"}, - {file = "pytokens-0.4.1-py3-none-any.whl", hash = "sha256:26cef14744a8385f35d0e095dc8b3a7583f6c953c2e3d269c7f82484bf5ad2de"}, - {file = "pytokens-0.4.1.tar.gz", hash = "sha256:292052fe80923aae2260c073f822ceba21f3872ced9a68bb7953b348e561179a"}, -] - -[package.extras] -dev = ["black", "build", "mypy", "pytest", "pytest-cov", "setuptools", "tox", "twine", "wheel"] - -[[package]] -name = "pyyaml" -version = "6.0.3" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "PyYAML-6.0.3-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f"}, - {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4"}, - {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3"}, - {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6"}, - {file = "PyYAML-6.0.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369"}, - {file = "PyYAML-6.0.3-cp38-cp38-win32.whl", hash = "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295"}, - {file = "PyYAML-6.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b"}, - {file = "pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b"}, - {file = "pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956"}, - {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8"}, - {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198"}, - {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b"}, - {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0"}, - {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69"}, - {file = "pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e"}, - {file = "pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c"}, - {file = "pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e"}, - {file = "pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824"}, - {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c"}, - {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00"}, - {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d"}, - {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a"}, - {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4"}, - {file = "pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b"}, - {file = "pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf"}, - {file = "pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196"}, - {file = "pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0"}, - {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28"}, - {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c"}, - {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc"}, - {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e"}, - {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea"}, - {file = "pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5"}, - {file = "pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b"}, - {file = "pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd"}, - {file = "pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8"}, - {file = "pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1"}, - {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c"}, - {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5"}, - {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6"}, - {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6"}, - {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be"}, - {file = "pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26"}, - {file = "pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c"}, - {file = "pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb"}, - {file = "pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac"}, - {file = "pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310"}, - {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7"}, - {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788"}, - {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5"}, - {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764"}, - {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35"}, - {file = "pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac"}, - {file = "pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3"}, - {file = "pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3"}, - {file = "pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba"}, - {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c"}, - {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702"}, - {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c"}, - {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065"}, - {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65"}, - {file = "pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9"}, - {file = "pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b"}, - {file = "pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da"}, - {file = "pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917"}, - {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9"}, - {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5"}, - {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a"}, - {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926"}, - {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7"}, - {file = "pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0"}, - {file = "pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007"}, - {file = "pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f"}, -] - -[[package]] -name = "pyzmq" -version = "27.1.0" -description = "Python bindings for 0MQ" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "pyzmq-27.1.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:508e23ec9bc44c0005c4946ea013d9317ae00ac67778bd47519fdf5a0e930ff4"}, - {file = "pyzmq-27.1.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:507b6f430bdcf0ee48c0d30e734ea89ce5567fd7b8a0f0044a369c176aa44556"}, - {file = "pyzmq-27.1.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf7b38f9fd7b81cb6d9391b2946382c8237fd814075c6aa9c3b746d53076023b"}, - {file = "pyzmq-27.1.0-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03ff0b279b40d687691a6217c12242ee71f0fba28bf8626ff50e3ef0f4410e1e"}, - {file = "pyzmq-27.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:677e744fee605753eac48198b15a2124016c009a11056f93807000ab11ce6526"}, - {file = "pyzmq-27.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dd2fec2b13137416a1c5648b7009499bcc8fea78154cd888855fa32514f3dad1"}, - {file = "pyzmq-27.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:08e90bb4b57603b84eab1d0ca05b3bbb10f60c1839dc471fc1c9e1507bef3386"}, - {file = "pyzmq-27.1.0-cp310-cp310-win32.whl", hash = "sha256:a5b42d7a0658b515319148875fcb782bbf118dd41c671b62dae33666c2213bda"}, - {file = "pyzmq-27.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:c0bb87227430ee3aefcc0ade2088100e528d5d3298a0a715a64f3d04c60ba02f"}, - {file = "pyzmq-27.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:9a916f76c2ab8d045b19f2286851a38e9ac94ea91faf65bd64735924522a8b32"}, - {file = "pyzmq-27.1.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:226b091818d461a3bef763805e75685e478ac17e9008f49fce2d3e52b3d58b86"}, - {file = "pyzmq-27.1.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:0790a0161c281ca9723f804871b4027f2e8b5a528d357c8952d08cd1a9c15581"}, - {file = "pyzmq-27.1.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c895a6f35476b0c3a54e3eb6ccf41bf3018de937016e6e18748317f25d4e925f"}, - {file = "pyzmq-27.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5bbf8d3630bf96550b3be8e1fc0fea5cbdc8d5466c1192887bd94869da17a63e"}, - {file = "pyzmq-27.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:15c8bd0fe0dabf808e2d7a681398c4e5ded70a551ab47482067a572c054c8e2e"}, - {file = "pyzmq-27.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bafcb3dd171b4ae9f19ee6380dfc71ce0390fefaf26b504c0e5f628d7c8c54f2"}, - {file = "pyzmq-27.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e829529fcaa09937189178115c49c504e69289abd39967cd8a4c215761373394"}, - {file = "pyzmq-27.1.0-cp311-cp311-win32.whl", hash = "sha256:6df079c47d5902af6db298ec92151db82ecb557af663098b92f2508c398bb54f"}, - {file = "pyzmq-27.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:190cbf120fbc0fc4957b56866830def56628934a9d112aec0e2507aa6a032b97"}, - {file = "pyzmq-27.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:eca6b47df11a132d1745eb3b5b5e557a7dae2c303277aa0e69c6ba91b8736e07"}, - {file = "pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc"}, - {file = "pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113"}, - {file = "pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233"}, - {file = "pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31"}, - {file = "pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28"}, - {file = "pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856"}, - {file = "pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496"}, - {file = "pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd"}, - {file = "pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf"}, - {file = "pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f"}, - {file = "pyzmq-27.1.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5"}, - {file = "pyzmq-27.1.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6"}, - {file = "pyzmq-27.1.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7"}, - {file = "pyzmq-27.1.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05"}, - {file = "pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9"}, - {file = "pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128"}, - {file = "pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39"}, - {file = "pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97"}, - {file = "pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db"}, - {file = "pyzmq-27.1.0-cp313-cp313t-win32.whl", hash = "sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c"}, - {file = "pyzmq-27.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2"}, - {file = "pyzmq-27.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e"}, - {file = "pyzmq-27.1.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a"}, - {file = "pyzmq-27.1.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea"}, - {file = "pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96"}, - {file = "pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d"}, - {file = "pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146"}, - {file = "pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd"}, - {file = "pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a"}, - {file = "pyzmq-27.1.0-cp314-cp314t-win32.whl", hash = "sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92"}, - {file = "pyzmq-27.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0"}, - {file = "pyzmq-27.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7"}, - {file = "pyzmq-27.1.0-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:18339186c0ed0ce5835f2656cdfb32203125917711af64da64dbaa3d949e5a1b"}, - {file = "pyzmq-27.1.0-cp38-cp38-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:753d56fba8f70962cd8295fb3edb40b9b16deaa882dd2b5a3a2039f9ff7625aa"}, - {file = "pyzmq-27.1.0-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b721c05d932e5ad9ff9344f708c96b9e1a485418c6618d765fca95d4daacfbef"}, - {file = "pyzmq-27.1.0-cp38-cp38-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7be883ff3d722e6085ee3f4afc057a50f7f2e0c72d289fd54df5706b4e3d3a50"}, - {file = "pyzmq-27.1.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:b2e592db3a93128daf567de9650a2f3859017b3f7a66bc4ed6e4779d6034976f"}, - {file = "pyzmq-27.1.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad68808a61cbfbbae7ba26d6233f2a4aa3b221de379ce9ee468aa7a83b9c36b0"}, - {file = "pyzmq-27.1.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:e2687c2d230e8d8584fbea433c24382edfeda0c60627aca3446aa5e58d5d1831"}, - {file = "pyzmq-27.1.0-cp38-cp38-win32.whl", hash = "sha256:a1aa0ee920fb3825d6c825ae3f6c508403b905b698b6460408ebd5bb04bbb312"}, - {file = "pyzmq-27.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:df7cd397ece96cf20a76fae705d40efbab217d217897a5053267cd88a700c266"}, - {file = "pyzmq-27.1.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:96c71c32fff75957db6ae33cd961439f386505c6e6b377370af9b24a1ef9eafb"}, - {file = "pyzmq-27.1.0-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:49d3980544447f6bd2968b6ac913ab963a49dcaa2d4a2990041f16057b04c429"}, - {file = "pyzmq-27.1.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:849ca054d81aa1c175c49484afaaa5db0622092b5eccb2055f9f3bb8f703782d"}, - {file = "pyzmq-27.1.0-cp39-cp39-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3970778e74cb7f85934d2b926b9900e92bfe597e62267d7499acc39c9c28e345"}, - {file = "pyzmq-27.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:da96ecdcf7d3919c3be2de91a8c513c186f6762aa6cf7c01087ed74fad7f0968"}, - {file = "pyzmq-27.1.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9541c444cfe1b1c0156c5c86ece2bb926c7079a18e7b47b0b1b3b1b875e5d098"}, - {file = "pyzmq-27.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e30a74a39b93e2e1591b58eb1acef4902be27c957a8720b0e368f579b82dc22f"}, - {file = "pyzmq-27.1.0-cp39-cp39-win32.whl", hash = "sha256:b1267823d72d1e40701dcba7edc45fd17f71be1285557b7fe668887150a14b78"}, - {file = "pyzmq-27.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:0c996ded912812a2fcd7ab6574f4ad3edc27cb6510349431e4930d4196ade7db"}, - {file = "pyzmq-27.1.0-cp39-cp39-win_arm64.whl", hash = "sha256:346e9ba4198177a07e7706050f35d733e08c1c1f8ceacd5eb6389d653579ffbc"}, - {file = "pyzmq-27.1.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c17e03cbc9312bee223864f1a2b13a99522e0dc9f7c5df0177cd45210ac286e6"}, - {file = "pyzmq-27.1.0-pp310-pypy310_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:f328d01128373cb6763823b2b4e7f73bdf767834268c565151eacb3b7a392f90"}, - {file = "pyzmq-27.1.0-pp310-pypy310_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c1790386614232e1b3a40a958454bdd42c6d1811837b15ddbb052a032a43f62"}, - {file = "pyzmq-27.1.0-pp310-pypy310_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:448f9cb54eb0cee4732b46584f2710c8bc178b0e5371d9e4fc8125201e413a74"}, - {file = "pyzmq-27.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:05b12f2d32112bf8c95ef2e74ec4f1d4beb01f8b5e703b38537f8849f92cb9ba"}, - {file = "pyzmq-27.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:18770c8d3563715387139060d37859c02ce40718d1faf299abddcdcc6a649066"}, - {file = "pyzmq-27.1.0-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:ac25465d42f92e990f8d8b0546b01c391ad431c3bf447683fdc40565941d0604"}, - {file = "pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53b40f8ae006f2734ee7608d59ed661419f087521edbfc2149c3932e9c14808c"}, - {file = "pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f605d884e7c8be8fe1aa94e0a783bf3f591b84c24e4bc4f3e7564c82ac25e271"}, - {file = "pyzmq-27.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c9f7f6e13dff2e44a6afeaf2cf54cee5929ad64afaf4d40b50f93c58fc687355"}, - {file = "pyzmq-27.1.0-pp38-pypy38_pp73-macosx_10_15_x86_64.whl", hash = "sha256:50081a4e98472ba9f5a02850014b4c9b629da6710f8f14f3b15897c666a28f1b"}, - {file = "pyzmq-27.1.0-pp38-pypy38_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:510869f9df36ab97f89f4cff9d002a89ac554c7ac9cadd87d444aa4cf66abd27"}, - {file = "pyzmq-27.1.0-pp38-pypy38_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1f8426a01b1c4098a750973c37131cf585f61c7911d735f729935a0c701b68d3"}, - {file = "pyzmq-27.1.0-pp38-pypy38_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:726b6a502f2e34c6d2ada5e702929586d3ac948a4dbbb7fed9854ec8c0466027"}, - {file = "pyzmq-27.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:bd67e7c8f4654bef471c0b1ca6614af0b5202a790723a58b79d9584dc8022a78"}, - {file = "pyzmq-27.1.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:722ea791aa233ac0a819fc2c475e1292c76930b31f1d828cb61073e2fe5e208f"}, - {file = "pyzmq-27.1.0-pp39-pypy39_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:01f9437501886d3a1dd4b02ef59fb8cc384fa718ce066d52f175ee49dd5b7ed8"}, - {file = "pyzmq-27.1.0-pp39-pypy39_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4a19387a3dddcc762bfd2f570d14e2395b2c9701329b266f83dd87a2b3cbd381"}, - {file = "pyzmq-27.1.0-pp39-pypy39_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c618fbcd069e3a29dcd221739cacde52edcc681f041907867e0f5cc7e85f172"}, - {file = "pyzmq-27.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ff8d114d14ac671d88c89b9224c63d6c4e5a613fe8acd5594ce53d752a3aafe9"}, - {file = "pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540"}, -] - -[package.dependencies] -cffi = {version = "*", markers = "implementation_name == \"pypy\""} - -[[package]] -name = "rdflib" -version = "7.5.0" -description = "RDFLib is a Python library for working with RDF, a simple yet powerful language for representing information." -optional = false -python-versions = ">=3.8.1" -groups = ["main"] -files = [ - {file = "rdflib-7.5.0-py3-none-any.whl", hash = "sha256:b011dfc40d0fc8a44252e906dcd8fc806a7859bc231be190c37e9568a31ac572"}, - {file = "rdflib-7.5.0.tar.gz", hash = "sha256:663083443908b1830e567350d72e74d9948b310f827966358d76eebdc92bf592"}, -] - -[package.dependencies] -pyparsing = ">=2.1.0,<4" - -[package.extras] -berkeleydb = ["berkeleydb (>=18.1.0,<19.0.0)"] -html = ["html5rdf (>=1.2,<2)"] -lxml = ["lxml (>=4.3,<6.0)"] -networkx = ["networkx (>=2,<4)"] -orjson = ["orjson (>=3.9.14,<4)"] -rdf4j = ["httpx (>=0.28.1,<0.29.0)"] - -[[package]] -name = "referencing" -version = "0.37.0" -description = "JSON Referencing + Python" -optional = false -python-versions = ">=3.10" -groups = ["docs"] -files = [ - {file = "referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231"}, - {file = "referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8"}, -] - -[package.dependencies] -attrs = ">=22.2.0" -rpds-py = ">=0.7.0" -typing-extensions = {version = ">=4.4.0", markers = "python_version < \"3.13\""} - -[[package]] -name = "requests" -version = "2.32.5" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.9" -groups = ["main", "docs", "test"] -files = [ - {file = "requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6"}, - {file = "requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset_normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "roman-numerals" -version = "4.0.0" -description = "Manipulate well-formed Roman numerals" -optional = false -python-versions = ">=3.10" -groups = ["docs"] -files = [ - {file = "roman_numerals-4.0.0-py3-none-any.whl", hash = "sha256:4131feb23ba1a542494873e4cee7844ec8d226a750134efc65ceb20939ed33c9"}, - {file = "roman_numerals-4.0.0.tar.gz", hash = "sha256:231287018a8788bf8c0718482a08c15b90458523ea1d840a18a791a86d4583b3"}, -] - -[[package]] -name = "rpds-py" -version = "0.30.0" -description = "Python bindings to Rust's persistent data structures (rpds)" -optional = false -python-versions = ">=3.10" -groups = ["docs"] -files = [ - {file = "rpds_py-0.30.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288"}, - {file = "rpds_py-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00"}, - {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6"}, - {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7"}, - {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324"}, - {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df"}, - {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3"}, - {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221"}, - {file = "rpds_py-0.30.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7"}, - {file = "rpds_py-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff"}, - {file = "rpds_py-0.30.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7"}, - {file = "rpds_py-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139"}, - {file = "rpds_py-0.30.0-cp310-cp310-win32.whl", hash = "sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464"}, - {file = "rpds_py-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169"}, - {file = "rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425"}, - {file = "rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d"}, - {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4"}, - {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f"}, - {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4"}, - {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97"}, - {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89"}, - {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d"}, - {file = "rpds_py-0.30.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038"}, - {file = "rpds_py-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7"}, - {file = "rpds_py-0.30.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed"}, - {file = "rpds_py-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85"}, - {file = "rpds_py-0.30.0-cp311-cp311-win32.whl", hash = "sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c"}, - {file = "rpds_py-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825"}, - {file = "rpds_py-0.30.0-cp311-cp311-win_arm64.whl", hash = "sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229"}, - {file = "rpds_py-0.30.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad"}, - {file = "rpds_py-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05"}, - {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28"}, - {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd"}, - {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f"}, - {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1"}, - {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23"}, - {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6"}, - {file = "rpds_py-0.30.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51"}, - {file = "rpds_py-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5"}, - {file = "rpds_py-0.30.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e"}, - {file = "rpds_py-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394"}, - {file = "rpds_py-0.30.0-cp312-cp312-win32.whl", hash = "sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf"}, - {file = "rpds_py-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b"}, - {file = "rpds_py-0.30.0-cp312-cp312-win_arm64.whl", hash = "sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e"}, - {file = "rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2"}, - {file = "rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8"}, - {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4"}, - {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136"}, - {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7"}, - {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2"}, - {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6"}, - {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e"}, - {file = "rpds_py-0.30.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d"}, - {file = "rpds_py-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7"}, - {file = "rpds_py-0.30.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31"}, - {file = "rpds_py-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95"}, - {file = "rpds_py-0.30.0-cp313-cp313-win32.whl", hash = "sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d"}, - {file = "rpds_py-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15"}, - {file = "rpds_py-0.30.0-cp313-cp313-win_arm64.whl", hash = "sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1"}, - {file = "rpds_py-0.30.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a"}, - {file = "rpds_py-0.30.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e"}, - {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000"}, - {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db"}, - {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2"}, - {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa"}, - {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083"}, - {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9"}, - {file = "rpds_py-0.30.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0"}, - {file = "rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94"}, - {file = "rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08"}, - {file = "rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27"}, - {file = "rpds_py-0.30.0-cp313-cp313t-win32.whl", hash = "sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6"}, - {file = "rpds_py-0.30.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d"}, - {file = "rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0"}, - {file = "rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be"}, - {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f"}, - {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f"}, - {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87"}, - {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18"}, - {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad"}, - {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07"}, - {file = "rpds_py-0.30.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f"}, - {file = "rpds_py-0.30.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65"}, - {file = "rpds_py-0.30.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f"}, - {file = "rpds_py-0.30.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53"}, - {file = "rpds_py-0.30.0-cp314-cp314-win32.whl", hash = "sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed"}, - {file = "rpds_py-0.30.0-cp314-cp314-win_amd64.whl", hash = "sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950"}, - {file = "rpds_py-0.30.0-cp314-cp314-win_arm64.whl", hash = "sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6"}, - {file = "rpds_py-0.30.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb"}, - {file = "rpds_py-0.30.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8"}, - {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7"}, - {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898"}, - {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e"}, - {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419"}, - {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551"}, - {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8"}, - {file = "rpds_py-0.30.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5"}, - {file = "rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404"}, - {file = "rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856"}, - {file = "rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40"}, - {file = "rpds_py-0.30.0-cp314-cp314t-win32.whl", hash = "sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0"}, - {file = "rpds_py-0.30.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3"}, - {file = "rpds_py-0.30.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58"}, - {file = "rpds_py-0.30.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a"}, - {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb"}, - {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c"}, - {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3"}, - {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5"}, - {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738"}, - {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f"}, - {file = "rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877"}, - {file = "rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a"}, - {file = "rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4"}, - {file = "rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e"}, - {file = "rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84"}, -] - -[[package]] -name = "s3transfer" -version = "0.19.2" -description = "An Amazon S3 Transfer Manager" -optional = false -python-versions = ">=3.10" -groups = ["dev"] -files = [ - {file = "s3transfer-0.19.2-py3-none-any.whl", hash = "sha256:d8168eccca828cbb2cd573675333f3bddd254313a9c42494b84c76b539e8ba25"}, - {file = "s3transfer-0.19.2.tar.gz", hash = "sha256:ba0309fd86be3c27dbf78cdd813c13c5e1df16e5874b99d2535ebbdfb9892993"}, -] - -[package.dependencies] -botocore = ">=1.37.4,<2.0a.0" - -[package.extras] -crt = ["botocore[crt] (>=1.37.4,<2.0a.0)"] - -[[package]] -name = "six" -version = "1.17.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main", "dev", "docs"] -files = [ - {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, - {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, -] - -[[package]] -name = "snowballstemmer" -version = "3.0.1" -description = "This package provides 32 stemmers for 30 languages generated from Snowball algorithms." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*" -groups = ["docs"] -files = [ - {file = "snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064"}, - {file = "snowballstemmer-3.0.1.tar.gz", hash = "sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895"}, -] - -[[package]] -name = "soupsieve" -version = "2.8.4" -description = "A modern CSS selector implementation for Beautiful Soup." -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "soupsieve-2.8.4-py3-none-any.whl", hash = "sha256:e7e6b0769c8f51ed59acab6e994b00621096cfb1c640a7509295987388fbaf65"}, - {file = "soupsieve-2.8.4.tar.gz", hash = "sha256:e121fd02e975c695e4e9e8774a5ee35d74714b59307868dcc5319ad2d9e3328e"}, -] - -[[package]] -name = "sphinx" -version = "9.0.4" -description = "Python documentation generator" -optional = false -python-versions = ">=3.11" -groups = ["docs"] -files = [ - {file = "sphinx-9.0.4-py3-none-any.whl", hash = "sha256:5bebc595a5e943ea248b99c13814c1c5e10b3ece718976824ffa7959ff95fffb"}, - {file = "sphinx-9.0.4.tar.gz", hash = "sha256:594ef59d042972abbc581d8baa577404abe4e6c3b04ef61bd7fc2acbd51f3fa3"}, -] - -[package.dependencies] -alabaster = ">=0.7.14" -babel = ">=2.13" -colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""} -docutils = ">=0.20,<0.23" -imagesize = ">=1.3" -Jinja2 = ">=3.1" -packaging = ">=23.0" -Pygments = ">=2.17" -requests = ">=2.30.0" -roman-numerals = ">=1.0.0" -snowballstemmer = ">=2.2" -sphinxcontrib-applehelp = ">=1.0.7" -sphinxcontrib-devhelp = ">=1.0.6" -sphinxcontrib-htmlhelp = ">=2.0.6" -sphinxcontrib-jsmath = ">=1.0.1" -sphinxcontrib-qthelp = ">=1.0.6" -sphinxcontrib-serializinghtml = ">=1.1.9" - -[[package]] -name = "sphinx-copybutton" -version = "0.5.2" -description = "Add a copy button to each of your code cells." -optional = false -python-versions = ">=3.7" -groups = ["docs"] -files = [ - {file = "sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd"}, - {file = "sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e"}, -] - -[package.dependencies] -sphinx = ">=1.8" - -[package.extras] -code-style = ["pre-commit (==2.12.1)"] -rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"] - -[[package]] -name = "sphinxcontrib-applehelp" -version = "2.0.0" -description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, - {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-devhelp" -version = "2.0.0" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, - {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-htmlhelp" -version = "2.1.0" -description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, - {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["html5lib", "pytest"] - -[[package]] -name = "sphinxcontrib-jsmath" -version = "1.0.1" -description = "A sphinx extension which renders display math in HTML via JavaScript" -optional = false -python-versions = ">=3.5" -groups = ["docs"] -files = [ - {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, - {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, -] - -[package.extras] -test = ["flake8", "mypy", "pytest"] - -[[package]] -name = "sphinxcontrib-qthelp" -version = "2.0.0" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, - {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["defusedxml (>=0.7.1)", "pytest"] - -[[package]] -name = "sphinxcontrib-serializinghtml" -version = "2.0.0" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, - {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}, -] - -[package.extras] -lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] -standalone = ["Sphinx (>=5)"] -test = ["pytest"] - -[[package]] -name = "sphinxtesters" -version = "0.2.4" -description = "Utilities for testing Sphinx extensions" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "sphinxtesters-0.2.4.tar.gz", hash = "sha256:09c456e1cd61ec99b64851e2990d2152fdf05bb53d87f3b294f22d73f939d6ca"}, -] - -[package.dependencies] -sphinx = ">=1.4" - -[package.extras] -doc = ["ghp-import", "numpydoc"] -test = ["pytest"] - -[[package]] -name = "stack-data" -version = "0.6.3" -description = "Extract data from python stack frames and tracebacks for informative displays" -optional = false -python-versions = "*" -groups = ["docs"] -files = [ - {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, - {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, -] - -[package.dependencies] -asttokens = ">=2.1.0" -executing = ">=1.2.0" -pure-eval = "*" - -[package.extras] -tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] - -[[package]] -name = "texext" -version = "0.6.8" -description = "Sphinx extensions for working with LaTeX math" -optional = false -python-versions = "*" -groups = ["docs"] -files = [ - {file = "texext-0.6.8.tar.gz", hash = "sha256:6c3ccc5578f93a1bd0051fcba25e92d259620d3d9c9031738570e7d78603e7a3"}, -] - -[package.dependencies] -docutils = ">=0.19" -sphinx = ">=7" - -[package.extras] -test = ["matplotlib (>=3.4)", "packaging", "pytest", "sphinxtesters (>=0.2.3)", "sympy (>=1.1)"] - -[[package]] -name = "tinycss2" -version = "1.4.0" -description = "A tiny CSS parser" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289"}, - {file = "tinycss2-1.4.0.tar.gz", hash = "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7"}, -] - -[package.dependencies] -webencodings = ">=0.4" - -[package.extras] -doc = ["sphinx", "sphinx_rtd_theme"] -test = ["pytest", "ruff"] - -[[package]] -name = "tornado" -version = "6.5.7" -description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "tornado-6.5.7-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:148b2eb15c2c765a50796172c1e499649b35f30d2e3c3d3e15913cfa56bfb163"}, - {file = "tornado-6.5.7-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9da38de27f1da3b78a966f0dae12b5a1ea9afe72ca805d84ff06508272ddf100"}, - {file = "tornado-6.5.7-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8d759e71906ee783f8867b93bf26a265743da4c1e2f4a018464c1ba019862972"}, - {file = "tornado-6.5.7-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a46347a18f23fb92b396beebe0fb78f61dda0cc302445202c16203d8a18848b"}, - {file = "tornado-6.5.7-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7778b30bef919231265e91c69963ce0f49a1e9c07ac900bbe75b19ce2575ba92"}, - {file = "tornado-6.5.7-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e726f0c75da7726eec023aa62751ff8878bd2737e34fbdd33b1ae5897d2200f5"}, - {file = "tornado-6.5.7-cp39-abi3-win32.whl", hash = "sha256:f8de3bf12d3efdd0cbe7c8887868198f8a91415e3f29fcf258d9b8eb7b1d9ae4"}, - {file = "tornado-6.5.7-cp39-abi3-win_amd64.whl", hash = "sha256:de942f843533a039ef9fa3d9c88c7cd8a7c94553fb5ad0154270989b3d99a2c4"}, - {file = "tornado-6.5.7-cp39-abi3-win_arm64.whl", hash = "sha256:ff934fce95643af5f11efdae618eaa73d469dc588641e5c8d19295a0c65c4796"}, - {file = "tornado-6.5.7.tar.gz", hash = "sha256:66c513a76cda70d53907bc27cf1447557699c2e95aa48ba27a442ff61c3ddfc2"}, -] - -[[package]] -name = "traitlets" -version = "5.14.3" -description = "Traitlets Python configuration system" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, - {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, -] - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.2)", "pytest-mock", "pytest-mypy-testing"] - -[[package]] -name = "typing-extensions" -version = "4.15.0" -description = "Backported and Experimental Type Hints for Python 3.9+" -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, - {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, -] - -[[package]] -name = "tzdata" -version = "2025.3" -description = "Provider of IANA time zone data" -optional = false -python-versions = ">=2" -groups = ["main"] -markers = "sys_platform == \"win32\" or sys_platform == \"emscripten\"" -files = [ - {file = "tzdata-2025.3-py2.py3-none-any.whl", hash = "sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1"}, - {file = "tzdata-2025.3.tar.gz", hash = "sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7"}, -] - -[[package]] -name = "urllib3" -version = "2.7.0" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.10" -groups = ["main", "dev", "docs", "test"] -files = [ - {file = "urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897"}, - {file = "urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c"}, -] - -[package.extras] -brotli = ["brotli (>=1.2.0) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=1.2.0.0) ; platform_python_implementation != \"CPython\""] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""] - -[[package]] -name = "virtualenv" -version = "20.36.1" -description = "Virtual Python Environment builder" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "virtualenv-20.36.1-py3-none-any.whl", hash = "sha256:575a8d6b124ef88f6f51d56d656132389f961062a9177016a50e4f507bbcc19f"}, - {file = "virtualenv-20.36.1.tar.gz", hash = "sha256:8befb5c81842c641f8ee658481e42641c68b5eab3521d8e092d18320902466ba"}, -] - -[package.dependencies] -distlib = ">=0.3.7,<1" -filelock = {version = ">=3.20.1,<4", markers = "python_version >= \"3.10\""} -platformdirs = ">=3.9.1,<5" - -[package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8) ; platform_python_implementation == \"PyPy\" or platform_python_implementation == \"GraalVM\" or platform_python_implementation == \"CPython\" and sys_platform == \"win32\" and python_version >= \"3.13\"", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10) ; platform_python_implementation == \"CPython\""] - -[[package]] -name = "wcwidth" -version = "0.2.14" -description = "Measures the displayed width of unicode strings in a terminal" -optional = false -python-versions = ">=3.6" -groups = ["docs"] -files = [ - {file = "wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1"}, - {file = "wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605"}, -] - -[[package]] -name = "webencodings" -version = "0.5.1" -description = "Character encoding aliases for legacy web content" -optional = false -python-versions = "*" -groups = ["docs"] -files = [ - {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, - {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, -] - -[metadata] -lock-version = "2.1" -python-versions = ">=3.11,<3.14" -content-hash = "1ce022d3f521d7a84f9aeb31af5997a5cf5e1dc19d97753582c2389712881d15" diff --git a/pyproject.toml b/pyproject.toml index 659e2758..e7b3fb8e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,50 +1,83 @@ -[tool.poetry] -authors = [ - "Vadim Abzalov vadim.i.abzalov@gmail.com", - "Nikita Kovalev Nikitoskova123@gmail.com", -] -description = "Python package containing Graphs and Grammars for experimental analysis of Context-Free Path Querying algorithms" -name = "cfpq_data" -package-mode = false +[project] +name = "cfpq-data" version = "5.0.0" +description = "Python package containing Graphs and Grammars for experimental analysis of Context-Free Path Querying algorithms" +readme = "README.rst" license = "Apache-2.0 AND CC-BY-4.0" +authors = [ + { name = "Vadim Abzalov", email = "vadim.i.abzalov@gmail.com" }, + { name = "Nikita Kovalev", email = "Nikitoskova123@gmail.com" }, +] +requires-python = ">=3.11,<3.14" +keywords = ["graphs", "grammars", "context-free", "path-query", "cfpq-data"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "Intended Audience :: Education", + "Operating System :: POSIX :: Linux", + "Operating System :: MacOS", + "Operating System :: Unix", + "Operating System :: Microsoft :: Windows", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3 :: Only", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Scientific/Engineering :: Bio-Informatics", + "Topic :: Scientific/Engineering :: Information Analysis", +] +dependencies = [ + "networkx>=3.6.1,<4.0.0", + "pandas>=2.3.3,<4.0.0", + "rdflib>=7.5.0,<8.0.0", + "requests>=2.32.5,<3.0.0", + "pyformlang==1.0.1", +] -[tool.poetry.dependencies] -python = ">=3.11,<3.14" -networkx = "^3.6.1" -pandas = ">=2.3.3,<4.0.0" -rdflib = "^7.5.0" -requests = "^2.32.5" -pyformlang = "1.0.1" +[project.urls] +Documentation = "https://formallanguageconstrainedpathquerying.github.io/CFPQ_Data" +"Source Code" = "https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data" +"Bug Tracker" = "https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues" -[tool.poetry.group.dev.dependencies] -pytest = "^9.0.2" -black = ">=25.12,<27.0" -pre-commit = "^4.5.1" -boto3 = "^1.43.86" +[dependency-groups] +dev = [ + "boto3>=1.43.86,<2.0.0", + "pre-commit>=4.5.1,<5.0.0", + "pyright>=1.1.414", + "ruff>=0.16.7,<0.17", + "ty>=0.0.81,<0.1", +] +test = [ + "pytest>=9.0.2,<10.0.0", + "pytest-cov>=7.0.0,<8.0.0", +] +docs = [ + "ipykernel>=7.1.0,<8.0.0", + "jupyter-client>=8.7.0,<9.0.0", + "nb2plots>=0.7.2,<0.8.0", + "numpydoc>=1.10.0,<2.0.0", + "pydata-sphinx-theme>=0.16.1,<0.22.0", + "sphinx>=9.0.4,<10.0.0", + "sphinx-copybutton>=0.5.2,<0.6.0", +] +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.poetry.group.test.dependencies] -codecov = "^2.1.13" -pytest = "^9.0.2" -pytest-cov = "^7.0.0" +[tool.hatch.build.targets.wheel] +packages = ["cfpq_data"] -[tool.poetry.group.docs.dependencies] -nb2plots = "^0.7.2" -numpydoc = "^1.10.0" -pydata-sphinx-theme = ">=0.16.1,<0.22.0" -sphinx = "^9.0.4" -sphinx-copybutton = "^0.5.2" -ipykernel = "^7.1.0" -jupyter-client = "^8.7.0" +[tool.hatch.build.targets.sdist] +include = [ + "cfpq_data", + "README.rst", + "LICENSE.txt", + "LICENSE-DATA.txt", +] [tool.pytest.ini_options] addopts = "--doctest-modules -vv -s" testpaths = ["cfpq_data", "tests"] - -[build-system] -requires = [ - "setuptools>=42", - "wheel" -] -build-backend = "setuptools.build_meta" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 64c94012..00000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ --r requirements/default.txt diff --git a/requirements/README.md b/requirements/README.md deleted file mode 100644 index 1642a9ff..00000000 --- a/requirements/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Requirements - -## Index - -- [`default.txt`](default.txt) - Default requirements -- [`developer.txt`](developer.txt) - Requirements for developers -- [`tests.txt`](tests.txt) - Requirements for running test suite -- [`docs.txt`](docs.txt) - Requirements for building the documentation (see `../doc/`) - -## Examples - -### Installing requirements - -```bash -pip install -U -r requirements/default.txt -``` - -### Running the tests - -```bash -pip install -U -r requirements/default.txt -pip install -U -r requirements/tests.txt -``` diff --git a/requirements/default.txt b/requirements/default.txt deleted file mode 100644 index 90d4c443..00000000 --- a/requirements/default.txt +++ /dev/null @@ -1,5 +0,0 @@ -networkx==3.6.1 -pandas==2.3.3 -pyformlang==1.0.1 -rdflib==7.6.0 -requests==2.33.0 diff --git a/requirements/developer.txt b/requirements/developer.txt deleted file mode 100644 index 17bd1e4b..00000000 --- a/requirements/developer.txt +++ /dev/null @@ -1,3 +0,0 @@ -black==26.3.1 -pre-commit==4.5.1 -pytest==9.0.3 diff --git a/requirements/docs.txt b/requirements/docs.txt deleted file mode 100644 index 3185069e..00000000 --- a/requirements/docs.txt +++ /dev/null @@ -1,5 +0,0 @@ -nb2plots==0.7.2 -numpydoc==1.10.0 -pydata_sphinx_theme==0.15.2 -sphinx==7.2.6 -sphinx-copybutton==0.5.2 diff --git a/requirements/tests.txt b/requirements/tests.txt deleted file mode 100644 index a5044e51..00000000 --- a/requirements/tests.txt +++ /dev/null @@ -1,3 +0,0 @@ -codecov>=2.1.13 -pytest>=9.0.2 -pytest-cov>=7.0.0 diff --git a/setup.py b/setup.py deleted file mode 100644 index e0ee76b7..00000000 --- a/setup.py +++ /dev/null @@ -1,92 +0,0 @@ -from pathlib import Path - -from setuptools import setup, find_packages - -root = Path(__file__).parent.resolve() - -with open(root / "README.rst", "r", encoding="utf-8") as f: - long_description = f.read() - -with open(root / "cfpq_data/config.py") as f: - for line in f: - if line.startswith("VERSION"): - version = line.strip().split()[-1][1:-1] - break - -name = "cfpq_data" - -description = ( - "Python package containing Graphs and Grammars " - + "for experimental analysis of Context-Free Path Querying algorithms" -) - -authors = { - "vdshk": ("Vadim Abzalov", "vadim.i.abzalov@gmail.com"), - "Yakonick": ("Nikita Kovalev", "Nikitoskova123@gmail.com"), -} - -url = "https://formallanguageconstrainedpathquerying.github.io/CFPQ_Data/" - -project_urls = { - "Documentation": "https://formallanguageconstrainedpathquerying.github.io/CFPQ_Data", - "Source Code": "https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data", - "Bug Tracker": "https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues", -} - -platforms = ["Linux", "Mac OSX", "Unix", "Windows"] - -keywords = ["graphs", "grammars", "context-free", "path-query", "cfpq-data"] - -classifiers = [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Intended Audience :: Science/Research", - "Intended Audience :: Education", - "License :: OSI Approved :: Apache Software License", - "Operating System :: POSIX :: Linux", - "Operating System :: MacOS", - "Operating System :: Unix", - "Operating System :: Microsoft :: Windows", - "Operating System :: OS Independent", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3 :: Only", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Scientific/Engineering :: Bio-Informatics", - "Topic :: Scientific/Engineering :: Information Analysis", -] - - -def parse_requirements_file(filename): - with open(filename) as fid: - requires = [l.strip() for l in fid.readlines() if not l.startswith("#")] - - return requires - - -install_requires = parse_requirements_file(root / "requirements" / "default.txt") -extras_require = { - dep: parse_requirements_file(root / "requirements" / f"{dep}.txt") - for dep in ["developer", "docs", "tests"] -} - -if __name__ == "__main__": - setup( - name="cfpq_data", - description=description, - long_description=long_description, - author=authors["vdshk"][0], - author_email=authors["vdshk"][1], - maintainer=authors["Yakonick"][0], - maintainer_email=authors["Yakonick"][1], - version=version, - keywords=keywords, - packages=find_packages(), - platforms=platforms, - url=url, - project_urls=project_urls, - classifiers=classifiers, - install_requires=install_requires, - extras_require=extras_require, - python_requires=">=3.11", - zip_safe=False, - ) diff --git a/utils/fetch_dataset.py b/utils/fetch_dataset.py deleted file mode 100644 index 3d01f25c..00000000 --- a/utils/fetch_dataset.py +++ /dev/null @@ -1,52 +0,0 @@ -import re -from collections import defaultdict -from json import dumps - -from boto3 import client - -from cfpq_data import __version__ as VERSION -from cfpq_data.config import AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, BUCKET_NAME -from config import MAIN_FOLDER - - -def fetch_dataset(): - DATASET_VERSION = VERSION - - if re.match(r"^(\d+)\.(\d+)\.(\d+)$", DATASET_VERSION) is not None: - DATASET_VERSION = ( - str(re.match(r"^(\d+)\.(\d+)\.(\d+)$", DATASET_VERSION).group(1)) + ".0.0" - ) - - s3 = client( - "s3", - aws_access_key_id=AWS_ACCESS_KEY_ID, - aws_secret_access_key=AWS_SECRET_ACCESS_KEY, - ) - - dataset = defaultdict(dict) - - for graph in s3.list_objects(Bucket="cfpq-data", Prefix=DATASET_VERSION)[ - "Contents" - ]: - graph_key = graph["Key"] - graph_class, graph_full_name = graph_key.split("/")[1:] - graph_name = graph_full_name.split(".")[0] - graph_file_extension = "." + graph_full_name.split(".")[1] - graph_archive_extension = graph_full_name.split(graph_file_extension)[1] - dataset[graph_class][graph_name] = { - "VersionId": s3.head_object(Bucket=BUCKET_NAME, Key=graph_key)["VersionId"], - "FileExtension": graph_file_extension, - "ArchiveExtension": graph_archive_extension, - } - - return dataset - - -def update_dataset(dataset): - with open(MAIN_FOLDER / "cfpq_data" / "dataset.py", "w") as fout: - fout.write("DATASET = " + dumps(dataset, indent=4)) - - -if __name__ == "__main__": - dataset = fetch_dataset() - update_dataset(dataset) diff --git a/utils/update_dataset_tables.py b/utils/update_dataset_tables.py deleted file mode 100644 index a885563a..00000000 --- a/utils/update_dataset_tables.py +++ /dev/null @@ -1,49 +0,0 @@ -from csv import DictWriter, QUOTE_MINIMAL - -from cfpq_data import graph_from_dataset -from cfpq_data.dataset import DATASET -from config import MAIN_FOLDER - - -def update_dataset_tables(dataset): - for graph_class in dataset.keys(): - table = list() - fieldnames = ["Graph", "#Vertices", "#Edges"] - - for graph_name in dataset[graph_class]: - graph = graph_from_dataset(graph_name) - table.append( - [ - graph_name, - f"{graph.number_of_nodes():,}", - f"{graph.number_of_edges():,}", - ] - ) - - table.sort(key=lambda row: int(row[2].replace(",", ""))) - - with open( - MAIN_FOLDER / "docs" / "dataset" / f"{graph_class}.csv", mode="w" - ) as csv_file: - csv_writer = DictWriter( - csv_file, - fieldnames=fieldnames, - delimiter=";", - quotechar='"', - quoting=QUOTE_MINIMAL, - ) - csv_writer.writeheader() - - for row in table: - csv_writer.writerow( - dict( - zip( - fieldnames, - row, - ) - ) - ) - - -if __name__ == "__main__": - update_dataset_tables(DATASET) diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..6c7f639f --- /dev/null +++ b/uv.lock @@ -0,0 +1,2152 @@ +version = 1 +revision = 3 +requires-python = ">=3.11, <3.14" +resolution-markers = [ + "python_full_version >= '3.12' and sys_platform == 'win32'", + "python_full_version < '3.12' and sys_platform == 'win32'", + "python_full_version >= '3.12' and sys_platform == 'emscripten'", + "python_full_version < '3.12' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] + +[[package]] +name = "accessible-pygments" +version = "0.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bc/c1/bbac6a50d02774f91572938964c582fff4270eee73ab822a4aeea4d8b11b/accessible_pygments-0.0.5.tar.gz", hash = "sha256:40918d3e6a2b619ad424cb91e556bd3bd8865443d9f22f1dcdf79e33c8046872", size = 1377899, upload-time = "2024-05-10T11:23:10.216Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl", hash = "sha256:88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7", size = 1395903, upload-time = "2024-05-10T11:23:08.421Z" }, +] + +[[package]] +name = "alabaster" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/f8/d9c74d0daf3f742840fd818d69cfae176fa332022fd44e3469487d5a9420/alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e", size = 24210, upload-time = "2024-07-26T18:15:03.762Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929, upload-time = "2024-07-26T18:15:02.05Z" }, +] + +[[package]] +name = "appnope" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/f7/a82489c2b6ebe32d3e2831895ae19c77861f0eadf3bb16034484d965dbb2/appnope-1.0.0.tar.gz", hash = "sha256:685db59cb6043c3c2e528adc0b3bce3a5f8d09bcf7492c6ea650d1b7421f3c49", size = 5454, upload-time = "2026-08-20T21:36:13.748Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/c7/6b687cb0f83d2a51017d47953f2ee430ffad6fec2a8ebc964e0718a33eb1/appnope-1.0.0-py3-none-any.whl", hash = "sha256:6fe0c04218aab65c54c4ff81638cdbf848d89f5653b74d68638a137f200dd16e", size = 4158, upload-time = "2026-08-20T21:36:12.444Z" }, +] + +[[package]] +name = "asttokens" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/25/1e/faf0f247f6f881b98fc4d6d07e14085cb89d13665084e6d6ac1dc2c03d0b/asttokens-3.0.2.tar.gz", hash = "sha256:3ecdbd8f2cc195f53ccada3a613538bb5f9ef6f6869129f13e03c30a677b8fe2", size = 63136, upload-time = "2026-07-12T03:31:49.084Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/2b/04b8a15f3a1c77bc79ddf5c73875327f34b4fa75982df2b76e45e402d364/asttokens-3.0.2-py3-none-any.whl", hash = "sha256:9da13157f5b28becde0bd374fc677dcd3c290614264eff096f167c469cd9f933", size = 28702, upload-time = "2026-07-12T03:31:47.542Z" }, +] + +[[package]] +name = "attrs" +version = "26.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, +] + +[[package]] +name = "babel" +version = "2.18.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/b2/51899539b6ceeeb420d40ed3cd4b7a40519404f9baf3d4ac99dc413a834b/babel-2.18.0.tar.gz", hash = "sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d", size = 9959554, upload-time = "2026-02-01T12:30:56.078Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl", hash = "sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35", size = 10196845, upload-time = "2026-02-01T12:30:53.445Z" }, +] + +[[package]] +name = "beautifulsoup4" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/43/65/318323f98dbee45d42dff61d8f047181bc6f2268a9068cfad035a46be5af/beautifulsoup4-4.15.0.tar.gz", hash = "sha256:288e3ca7d54b06f2ac191970bc275c1939cb46d450b255bf6718b04aa37ab4f7", size = 632571, upload-time = "2026-06-07T16:44:20.453Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/c6/92fcd42f1ba33e1184263f25bfabf3d27c383410470f169e4b8163bf9c17/beautifulsoup4-4.15.0-py3-none-any.whl", hash = "sha256:d6f88de62e1d4e38ecb1077eb9724cd0eff29d2a08ca16a401e9b9e93f117cf9", size = 109924, upload-time = "2026-06-07T16:44:21.566Z" }, +] + +[[package]] +name = "bleach" +version = "6.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/48/3c/e12ac860709702bd5ebeb9b56a4fe334f1001246ee1b8f2b7ee28912df7d/bleach-6.4.0.tar.gz", hash = "sha256:4202482733d85cedd04e59fcb2f89f4e4c7c385a78d3c3c23c30446843a37452", size = 204857, upload-time = "2026-06-05T13:01:13.734Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/9d/40b6267367182187139a4000b82a3b287d84d745bccd808e75d916920e9d/bleach-6.4.0-py3-none-any.whl", hash = "sha256:4b6b6a54fff2e69a3dde9d21cc6301220bee3c3cb792187d11403fd795031081", size = 165109, upload-time = "2026-06-05T13:01:12.504Z" }, +] + +[package.optional-dependencies] +css = [ + { name = "tinycss2" }, +] + +[[package]] +name = "boto3" +version = "1.43.95" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "botocore" }, + { name = "jmespath" }, + { name = "s3transfer" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/ed/9d4d4e7d4b874c16f7b3a886efe3e45801e0f9ebb60058adf1bb69cb2073/boto3-1.43.95.tar.gz", hash = "sha256:9d71f299111e1f4e8c28f573a1b7c0555fe40d2147fe9bef852a02bd57cbde60", size = 112666, upload-time = "2026-09-15T19:23:49.395Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/66/6e/9c6fb58b1cdddf13b3e9edc94e0c6e08fff456355f6e097684d6117aa8d4/boto3-1.43.95-py3-none-any.whl", hash = "sha256:c906921c4f9ab41e9587af6586f072c8f2be6979e8bde2ec26aa443bb1745019", size = 140026, upload-time = "2026-09-15T19:23:47.563Z" }, +] + +[[package]] +name = "botocore" +version = "1.43.95" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jmespath" }, + { name = "python-dateutil" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/2c/0031468b521eefed325a3da2d6576e068aab95837af0c96effea6438851c/botocore-1.43.95.tar.gz", hash = "sha256:779588da32bd48a7bb0c097da4bcb747260e86d2bfc507369dca56f1450e0722", size = 16106887, upload-time = "2026-09-15T19:23:44.23Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/77/7ce7c937b31903f1402e478fdc97f98e727656fcea3cb54e74f1ca55793e/botocore-1.43.95-py3-none-any.whl", hash = "sha256:0fda26d16c7c7bf7082c421390a817b696f98a43d3da7c43dbbb093f76662876", size = 15800616, upload-time = "2026-09-15T19:23:41.228Z" }, +] + +[[package]] +name = "certifi" +version = "2026.7.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/c2/24167ea9858356b47a87a50d39908bfdb72ceeefe0041586e704e5376b3a/certifi-2026.7.22.tar.gz", hash = "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55", size = 138112, upload-time = "2026-07-22T03:35:12.644Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775", size = 136983, upload-time = "2026-07-22T03:35:11.276Z" }, +] + +[[package]] +name = "cffi" +version = "2.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9e/ef/008a1939e372c06329a3fce4279c02f328488f3526744906eeec3da7ad5f/cffi-2.1.1.tar.gz", hash = "sha256:dd31f52ea1086513bb9df30f8fcee9b8918323ae067a3d5b78bc826a000712be", size = 530807, upload-time = "2026-08-03T21:21:18.939Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/d2/16d99a0c4948febc0ebd133a13b2f688ff7f8cb04da971e1128872ce0c03/cffi-2.1.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:c8d2c9fd1f2d16f780d15127abb050d13d1a76c03a4bd87d7e4980e45e511e12", size = 183838, upload-time = "2026-08-03T21:19:29.637Z" }, + { url = "https://files.pythonhosted.org/packages/cd/95/31b535a9f0220ae9f357de4a08d57ce89cb417653c2fd9f075f50822a388/cffi-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:398aff33cee2767e3e781d2554c54bd0dff386bb437581e0d8011fde1a942ec1", size = 184168, upload-time = "2026-08-03T21:19:30.764Z" }, + { url = "https://files.pythonhosted.org/packages/ad/5a/4707a0dc1f203f5dde5a907b0d4e3c25d71120241048bd5bc6f1bb9d4e71/cffi-2.1.1-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:154852545011f779917b11c78db2358d095da62a9a172b78ad0a583ee5adc0d0", size = 211805, upload-time = "2026-08-03T21:19:31.867Z" }, + { url = "https://files.pythonhosted.org/packages/ad/66/c19feabb28485b6e0bbaaafa90837a1ef5d302e90f2178bd33f17a49879b/cffi-2.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3311ed60d36f83378794e1009ac6258bafbf81f7888b4caa7b35a521e3f95813", size = 218716, upload-time = "2026-08-03T21:19:32.896Z" }, + { url = "https://files.pythonhosted.org/packages/a7/92/500760486c8baab49a7a8a58ba7fc3355ec3974b454b8a09e528efde9e1d/cffi-2.1.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6e192623c49c94421616a5778fba35cf0d5a8d000650c1967ef4448ee5cdd990", size = 205569, upload-time = "2026-08-03T21:19:34.142Z" }, + { url = "https://files.pythonhosted.org/packages/a5/a7/a67c733254d6e7373f7822f8082d8d6beade791e0cf12a7611f376fa61c7/cffi-2.1.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a6e721d4b0e45d5b65e87534470e67b18dcd092c83f68fba09f152b9cbc061af", size = 204907, upload-time = "2026-08-03T21:19:35.174Z" }, + { url = "https://files.pythonhosted.org/packages/f7/a4/4399daaf8f7dfee9d7c3327fdb0426ee041cc63edc358b93911ceb2bfc7a/cffi-2.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:34e261f78cb6ceaaa36f42f2613f4380d94d9c759a9c73c769ee6e0247364632", size = 217807, upload-time = "2026-08-03T21:19:36.286Z" }, + { url = "https://files.pythonhosted.org/packages/28/f7/dabe6da2466ecbd82dc62e7342dc6b1065dad990c06f00f0ede9ebf2a0ed/cffi-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7225e4514edb64eb6740324353e0da0711954fd8d7da4576755b1c6e09b697cd", size = 221252, upload-time = "2026-08-03T21:19:37.416Z" }, + { url = "https://files.pythonhosted.org/packages/ce/87/616202d8e51342c07d2534c510111c4cc37201775ce8f60802c9335d1edd/cffi-2.1.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df913725b79db7bcf03448f36b7bf8815363417d5b58deecf9305e3e30f0f21a", size = 214214, upload-time = "2026-08-03T21:19:38.507Z" }, + { url = "https://files.pythonhosted.org/packages/b4/c6/ab025d75d2c26c19b087c0124e75ee31cb65032f4fe345d356d8c507ab97/cffi-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f5cfbc5fe74540d335175b656c725d74d90e3730c626d92575eea35029d9afaa", size = 219408, upload-time = "2026-08-03T21:19:39.809Z" }, + { url = "https://files.pythonhosted.org/packages/db/e2/7e8109f65445bdc673a7b54f02c677de462db75674220fd1335efc8eb598/cffi-2.1.1-cp311-cp311-win32.whl", hash = "sha256:f8ec5e643a9a937f64e1999eb9f75d072263751912dc5cd06d3c85f8f44be7c3", size = 174470, upload-time = "2026-08-03T21:19:41.246Z" }, + { url = "https://files.pythonhosted.org/packages/73/c0/77ba02423c2f7d7091143c45cd49e0e6575c4c1967394bb542bd923a9b74/cffi-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:42f6930c31dc7f50732c9ae793c2786c7b6b044195967bbdde40bb9be81c4cc0", size = 185096, upload-time = "2026-08-03T21:19:42.615Z" }, + { url = "https://files.pythonhosted.org/packages/7c/47/9f1f85f9672ceda4984dc6c4f8824e8558992a2972c3d3c81fb8eb28d4ba/cffi-2.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:c7659f22557c5a0bc4855cd635f55edec690cc008a40768527762cb9fb263455", size = 179941, upload-time = "2026-08-03T21:19:43.747Z" }, + { url = "https://files.pythonhosted.org/packages/10/69/43965eccfdead3b9220015fd1320e117be8c6ed01a62ffab76eeb752f5d5/cffi-2.1.1-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:c8c69575568085ba0b1b10c0249d779a214aea6f6522e949a0fc9fb0fcb449d0", size = 184821, upload-time = "2026-08-03T21:19:44.887Z" }, + { url = "https://files.pythonhosted.org/packages/54/7d/16e5a096677b5e313ca80cd5e5170efa3ea44624a82bb111925522da64b1/cffi-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f81b3b8f3d4e343550fa4baa0e479bba9f2d29ce9c2e9b51d1ce1718d7442fcf", size = 184719, upload-time = "2026-08-03T21:19:46.129Z" }, + { url = "https://files.pythonhosted.org/packages/56/e6/8941622732edec876dd17d0453dce07317ae96db34f2ec1436c9d3785986/cffi-2.1.1-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:811bd1e21d32de12efca32393a0ab3f5133b54fce9bd44b8bd77ab07da14bf6a", size = 214799, upload-time = "2026-08-03T21:19:47.218Z" }, + { url = "https://files.pythonhosted.org/packages/44/de/f98430906df1545ffde0d543dd124a7a439bc2cd32b36b9c53f805df7333/cffi-2.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:68e62fe11f30d5ca8289242866f0a5291402d8529ca2178ab8afc5c9694ae890", size = 222389, upload-time = "2026-08-03T21:19:48.331Z" }, + { url = "https://files.pythonhosted.org/packages/6a/5b/717f1526b9957b34456313c31645c5b82b8fb5c3fe9e4752999be7128bfc/cffi-2.1.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:4a7c934f7360e8cd64fe9efadcbd10c7c6364f531e432b9a4bf5ccbc9e0e8b50", size = 210249, upload-time = "2026-08-03T21:19:49.543Z" }, + { url = "https://files.pythonhosted.org/packages/64/b3/f8aa4f3e34986c7e4ec45072d1b1b9dd295b6b18007b45518d79726dd725/cffi-2.1.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:3143d81e29e1e20a9ce10901ec369012947876596f75a222235965f2b7ae832e", size = 208775, upload-time = "2026-08-03T21:19:50.918Z" }, + { url = "https://files.pythonhosted.org/packages/b1/db/dceb9dd5b231e1da801793f8acc9f3c52a7e1afe40bb1aae37e02b0faad5/cffi-2.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c1453022f490d2459a11819d83ad1d586e9ff65a12ac3e705ffebd46d3685dcf", size = 221822, upload-time = "2026-08-03T21:19:52.054Z" }, + { url = "https://files.pythonhosted.org/packages/a0/d2/6cd24ae3be000a634109c247d1475d62e5616d0dc78c82770942ec384248/cffi-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:208f941bb9d18e768138677f0a6d2ce01f590df56043dda1df1535ac57c88517", size = 225232, upload-time = "2026-08-03T21:19:53.109Z" }, + { url = "https://files.pythonhosted.org/packages/cb/52/3fa190537004dd7f0ab860a6dc7c0175b8667f68d1e618a46f5498d30250/cffi-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:210019b6c7cf07f081b4c54635c8cf744377001350e29cc0f81c4377b4797735", size = 223597, upload-time = "2026-08-03T21:19:54.515Z" }, + { url = "https://files.pythonhosted.org/packages/80/fb/0bb75b7039588c074b37ae99f40d9bfddf990ecb2fbc346ebccd2e56b9be/cffi-2.1.1-cp312-cp312-win32.whl", hash = "sha256:046bfc24911b37851ee1b51aab8bffe713d89c68c6a057b09484ce9fd5f69b4e", size = 175292, upload-time = "2026-08-03T21:19:55.566Z" }, + { url = "https://files.pythonhosted.org/packages/d9/79/615cc094e2fb508cade7de88d3b4f6c4ec2bab695c97bce9153dc65aadf5/cffi-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:f53e442b08449d42821fa4a4fba000095af9f62742a500f978a9f557ec44339a", size = 185919, upload-time = "2026-08-03T21:19:56.89Z" }, + { url = "https://files.pythonhosted.org/packages/70/c6/d0ea84713fe46b243a436a18fcd47d639732747e21635c8a27191b06dc30/cffi-2.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:7bde5e4cc5c10140859842b9d383af292b22639a4dffb725314baf45968cef80", size = 180093, upload-time = "2026-08-03T21:19:58.155Z" }, + { url = "https://files.pythonhosted.org/packages/9d/f4/035513d4117049066b4779dc3b7c0c0fdad175fa13731c9f4003f1cd1478/cffi-2.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:b5bdfd1c873d4e093aabc0ca84c4ca6dbc4f752afb5c86f146d9742580c9da2e", size = 194248, upload-time = "2026-08-03T21:19:59.399Z" }, + { url = "https://files.pythonhosted.org/packages/76/af/2aeb4dbb5fc41a04161ae9ff1518de7cec08e164f44a8ce6a4cf7fd2cd1d/cffi-2.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:31348097ff5bbe827ccc41795d4dd099d9f0625e7def00ee653c137a490c2a6c", size = 196908, upload-time = "2026-08-03T21:20:00.746Z" }, + { url = "https://files.pythonhosted.org/packages/a7/46/2e5fdde8555706dd98139a910ca11be02809f3f605ce956f655d0214e100/cffi-2.1.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:9d2055050ea716bd38b7f7f1579c275386646b4894c155a3e2f3cd62ed41b7c6", size = 184805, upload-time = "2026-08-03T21:20:02.02Z" }, + { url = "https://files.pythonhosted.org/packages/55/41/4c7042f317b9217502988f0873af87e16ad606dc20f84e546e3e6ce9764c/cffi-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19ee6127ee34de7d83ce3d371ebc5ed91addbdcc39f9ab15ce4eb35a4e534971", size = 184764, upload-time = "2026-08-03T21:20:03.141Z" }, + { url = "https://files.pythonhosted.org/packages/43/1f/1c3d90d91811c8f86ced9ed637956c54bfe5b79ca98fe976d7f8c8979f6b/cffi-2.1.1-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6a8dddef476fab96d066d578fc88526767b836ab5ab21754e1d5bf3879c31c7c", size = 214722, upload-time = "2026-08-03T21:20:04.377Z" }, + { url = "https://files.pythonhosted.org/packages/37/6f/3b5ce4c3b2192d250f04908f2bfd91ef34552ec8f7716a5d4abdb8d67bb2/cffi-2.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f16c709686a78c727bbbf059f92b0bf41c6fc60deec706d2dc19f529175a6125", size = 222369, upload-time = "2026-08-03T21:20:05.544Z" }, + { url = "https://files.pythonhosted.org/packages/02/10/4b3c75dde3d9663c9e02ba05c2668b954f671d4bbe346413ca8c696b295a/cffi-2.1.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:fcd22650c908d7b7da162bbfaab594a1227a15d1643a98c68b122ac642fa2264", size = 210175, upload-time = "2026-08-03T21:20:06.75Z" }, + { url = "https://files.pythonhosted.org/packages/df/62/14f74b9543e605d17701dc797b815958b8bb70b7624ce1b832ddad48ed6c/cffi-2.1.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:aa9511c62d14da7aacc9b4bf51f3f697a621e83b2d6919008243c3aad168eea3", size = 208670, upload-time = "2026-08-03T21:20:08.04Z" }, + { url = "https://files.pythonhosted.org/packages/95/95/86342356ff5953b3fb06f7ef7c5bee212d45e770abc7218d451b9148313c/cffi-2.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a931079504ecc49efed7744c476a5c343a92fabf66dec2db95edb1b2fdc770e2", size = 221824, upload-time = "2026-08-03T21:20:09.274Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ff/7b3429ff53aafe931ed8a5fc69f481bbef7ba6de87ddcbb63d08f483f613/cffi-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a2d7755bef5a12ed488f4ef1f1b69ee9191d7396083b755a5d2295f6edb4768b", size = 225148, upload-time = "2026-08-03T21:20:10.7Z" }, + { url = "https://files.pythonhosted.org/packages/34/34/a95870b9221e09cf4f2ce3178b1a210abdfe63a1bd357da940418d7b8d15/cffi-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0bcb7e0f677f543555d2adff3bf19c05f66cdb4796e5ff602442ab2fe3c4ef7", size = 223564, upload-time = "2026-08-03T21:20:12.165Z" }, + { url = "https://files.pythonhosted.org/packages/70/ea/839b50531021a647fb5e929f72cf97bc1ff702b5472166164b5b6e76b851/cffi-2.1.1-cp313-cp313-win32.whl", hash = "sha256:334644fbac4eff73d985a17a91226df55d0f394160c4cfb880e084c8f7161cac", size = 175263, upload-time = "2026-08-03T21:20:13.559Z" }, + { url = "https://files.pythonhosted.org/packages/60/a6/8b149b2c3f2e11aaa1618ef64500b45f50f22c57a977a4dff1aff1f91042/cffi-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:1aa5645c30469b09530c4ebca77ebf8f17618293c58f8549cb1a543a50236e7d", size = 185688, upload-time = "2026-08-03T21:20:14.69Z" }, + { url = "https://files.pythonhosted.org/packages/01/9a/11f687cb39d6a3504060d5242f04f48c735afb4d3d533958a20594890cb2/cffi-2.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:63bbfd5ded17c4840ac07cd8f1c21ba9d9708141f840b324f422f41b207e3973", size = 180078, upload-time = "2026-08-03T21:20:15.917Z" }, +] + +[[package]] +name = "cfgv" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, +] + +[[package]] +name = "cfpq-data" +version = "5.0.0" +source = { editable = "." } +dependencies = [ + { name = "networkx" }, + { name = "pandas" }, + { name = "pyformlang" }, + { name = "rdflib" }, + { name = "requests" }, +] + +[package.dev-dependencies] +dev = [ + { name = "boto3" }, + { name = "pre-commit" }, + { name = "pyright" }, + { name = "ruff" }, + { name = "ty" }, +] +docs = [ + { name = "ipykernel" }, + { name = "jupyter-client" }, + { name = "nb2plots" }, + { name = "numpydoc" }, + { name = "pydata-sphinx-theme" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx-copybutton" }, +] +test = [ + { name = "pytest" }, + { name = "pytest-cov" }, +] + +[package.metadata] +requires-dist = [ + { name = "networkx", specifier = ">=3.6.1,<4.0.0" }, + { name = "pandas", specifier = ">=2.3.3,<4.0.0" }, + { name = "pyformlang", specifier = "==1.0.1" }, + { name = "rdflib", specifier = ">=7.5.0,<8.0.0" }, + { name = "requests", specifier = ">=2.32.5,<3.0.0" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "boto3", specifier = ">=1.43.86,<2.0.0" }, + { name = "pre-commit", specifier = ">=4.5.1,<5.0.0" }, + { name = "pyright", specifier = ">=1.1.414" }, + { name = "ruff", specifier = ">=0.16.7,<0.17" }, + { name = "ty", specifier = ">=0.0.81,<0.1" }, +] +docs = [ + { name = "ipykernel", specifier = ">=7.1.0,<8.0.0" }, + { name = "jupyter-client", specifier = ">=8.7.0,<9.0.0" }, + { name = "nb2plots", specifier = ">=0.7.2,<0.8.0" }, + { name = "numpydoc", specifier = ">=1.10.0,<2.0.0" }, + { name = "pydata-sphinx-theme", specifier = ">=0.16.1,<0.22.0" }, + { name = "sphinx", specifier = ">=9.0.4,<10.0.0" }, + { name = "sphinx-copybutton", specifier = ">=0.5.2,<0.6.0" }, +] +test = [ + { name = "pytest", specifier = ">=9.0.2,<10.0.0" }, + { name = "pytest-cov", specifier = ">=7.0.0,<8.0.0" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e5/3f/143b048436775b0f76ac3eec145c019e8173ccc2885c8f20319b996d5e83/charset_normalizer-3.5.1.tar.gz", hash = "sha256:6117b84ea48435e5356dc737f5121485c30920ba43375fa7b434fd753df0eac3", size = 171764, upload-time = "2026-08-15T08:20:44.807Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/b6/034f6802e9c3f6418966cfabb7db8c9252cc2429c5098f41cc43af804149/charset_normalizer-3.5.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eda059b6bc8bc0812d626fd91a7ce01bf583df0a61296eff390fd94141a34e30", size = 363585, upload-time = "2026-08-15T08:16:46.646Z" }, + { url = "https://files.pythonhosted.org/packages/d5/fa/6a7e2a7c4b5451912b8c417732df79574354443592a88d616de03da66ae5/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa2bb0b37202dca27175591f761108b5d34096ade1191ffe4808bdf6b1571488", size = 251189, upload-time = "2026-08-15T08:16:48.287Z" }, + { url = "https://files.pythonhosted.org/packages/a4/c8/ab42b07cfd82e919f427fcfaa7c41abae8242833ad1aad66d42bae40b669/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0b2b1b3fa5670c127b246df1d0c059defd41f689a868a3b9d79df9b1cac42d22", size = 239724, upload-time = "2026-08-15T08:16:49.67Z" }, + { url = "https://files.pythonhosted.org/packages/e7/80/b9348b5d3041209f98b4cdad7655766369233f1d533f4f4f7558e9717bec/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6e5e4d73d588ca5ed09df1b7dcd1b203d1df3c542e3f50d126c947d432b10731", size = 280078, upload-time = "2026-08-15T08:16:51.228Z" }, + { url = "https://files.pythonhosted.org/packages/82/38/083a24028304bc85bb9e376fed801178423dcbb67495f73b6ea0624e1894/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b54e7e13267d49ffbfe68e25b3cbd774dab38fa37238f71265e91b36146eb21c", size = 276650, upload-time = "2026-08-15T08:16:52.625Z" }, + { url = "https://files.pythonhosted.org/packages/0d/35/731ac04aa0a097fc1c97f0994c375bdb230c6c96619db794208fe664e9ce/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7b742bf31c88566b4bb6335a7f393bb322e580b6bb98df7bd0c25e6e3519ce8", size = 262325, upload-time = "2026-08-15T08:16:54.085Z" }, + { url = "https://files.pythonhosted.org/packages/f5/28/c2028e7021fb89c6e56868ed0e387b8e9aa811abdd2ab3208d6578d2c930/charset_normalizer-3.5.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6ba32c4d2abf1d2fe7cf27d280f4cca5664233b0f885549c7761719eb977f486", size = 261140, upload-time = "2026-08-15T08:16:55.604Z" }, + { url = "https://files.pythonhosted.org/packages/28/f0/0c0ceec6d98b7daa62e361e418135d59685811d79ba11529aad5cdf15e84/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0722590aabf9dc6a6c0343d523c05458fa2b5047dbe6302fd526bb570600753f", size = 252791, upload-time = "2026-08-15T08:16:57.103Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3e/48f4cd187b1c33189d86039e9cbe4f92c05454175504b44ff81806d4d1bf/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa1099b956fb795e686d073568f6dc002a0bb89765ea6d5b055dd7d9bf1b116c", size = 240730, upload-time = "2026-08-15T08:16:58.418Z" }, + { url = "https://files.pythonhosted.org/packages/42/85/f9e22af69af67c54cce42be9455d9c81294f918b4ccc454db01f66efcac2/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:bd6c173f04743d483881bffa1478d5a4624475b8cd1d2194956a75548e191c18", size = 280791, upload-time = "2026-08-15T08:16:59.918Z" }, + { url = "https://files.pythonhosted.org/packages/fd/4c/9044135f42127630b6fa742feb51256353f6ab87a78f2fdd1de3de955a7f/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:f298e218441525d3794428b4c8b8fb8662c6d3ea79925d4807ee6b9a96a3bca5", size = 259598, upload-time = "2026-08-15T08:17:01.421Z" }, + { url = "https://files.pythonhosted.org/packages/ba/ed/1dd7cfebb4e75812934c49ca3b79757d11948053f7937ab7070c151f3c55/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:6e2912d4babbc65196ac13c2f53468dc57fb8b9c25ef913e8c59ddf7c6dc0e1b", size = 278217, upload-time = "2026-08-15T08:17:02.782Z" }, + { url = "https://files.pythonhosted.org/packages/bf/eb/239c84503cc9e3ba6eb34686a24bc66e84f3924efdd7e38e751a19f6bc10/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3d27167433c0d5f18dc850f07d0b3816221984fecdc405d6c157a6f0b8f8e9e6", size = 263417, upload-time = "2026-08-15T08:17:04.216Z" }, + { url = "https://files.pythonhosted.org/packages/37/ab/4e4510e1e288478e2c8333131d1c1382382ba8cd2165053c79e39d1da961/charset_normalizer-3.5.1-cp311-cp311-win32.whl", hash = "sha256:ac00177c4831ffa650f8609e4bdddd5fe09c03b1c0c47acece7e6ea20421598b", size = 181774, upload-time = "2026-08-15T08:17:05.58Z" }, + { url = "https://files.pythonhosted.org/packages/e3/57/32f0ccea59e8612057c61d6fd22ef2cb63cca93c9fe594094919696ac170/charset_normalizer-3.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:f9b1e28d0e8dbfa858abdba91d6b547beaf2df1a59bec6da6faae7b96a4991a9", size = 206653, upload-time = "2026-08-15T08:17:07.075Z" }, + { url = "https://files.pythonhosted.org/packages/17/d4/b65c433fc521e58b5f54293982a5e51c05cb5f2dd3f1c7a6acb65b75324e/charset_normalizer-3.5.1-cp311-cp311-win_arm64.whl", hash = "sha256:ae31a1a1db2ee6cc2942fccaf695c934bc7f3db9f2133a3fef1f367cf1a4ab10", size = 185630, upload-time = "2026-08-15T08:17:08.502Z" }, + { url = "https://files.pythonhosted.org/packages/30/27/78873dc8b6a56357517b74b6bb9568b80450e7bb4f6ef7e3fa9d22aa0bd7/charset_normalizer-3.5.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:5b6d1386bf0096d26d3a863dc0a487a5b4eb9aa93cf5ba69683d29dde6b9d60f", size = 344456, upload-time = "2026-08-15T08:17:10.072Z" }, + { url = "https://files.pythonhosted.org/packages/9a/4c/be49ada26b1f0232d57aa89bbebf997a5cc2332a5616b6eca26ff680044d/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4582c27e8c889d64811987b5967fbd3ae0c823fe1fd933b543d55ac20bb475fa", size = 238530, upload-time = "2026-08-15T08:17:11.563Z" }, + { url = "https://files.pythonhosted.org/packages/76/84/6f1290fa07ae6978d3960caa3eb1b8019bf9284ab7c2297b00c099ef4250/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1d1c7a53a6c2103925cdd6d7229f8c567379f211c869793df679f2e9f738c369", size = 230200, upload-time = "2026-08-15T08:17:12.919Z" }, + { url = "https://files.pythonhosted.org/packages/e7/a0/47b18adeed31c8f16ba9700f32c1b18594cfa09f47eb672a488c273c22bf/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e6621fb2a4988d6e53eedc455e5903e2679f3967b8acb3d639f1b63c14a2e893", size = 262222, upload-time = "2026-08-15T08:17:14.571Z" }, + { url = "https://files.pythonhosted.org/packages/38/fe/341861ac118dae06f3ec0eb487488af52128f2ef2faf0b11003944d22259/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7c0c10730342b0c9b35dd1d619beb8214e520bd96a1f870f452680b238aab3e0", size = 258951, upload-time = "2026-08-15T08:17:16.158Z" }, + { url = "https://files.pythonhosted.org/packages/6f/89/bb5108dc6c3651dca963f2b0a3ba19bbcb370c94e1b6d3e0e844a58e6dca/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b9af956078716df40d985fb0dfeb2c2120c5ca92ba4ff4b388acfd01cdc14d08", size = 248801, upload-time = "2026-08-15T08:17:17.683Z" }, + { url = "https://files.pythonhosted.org/packages/b1/ba/ef83ae3aca816393decfa3530976f38a79812d707b80b580ac33b83f9877/charset_normalizer-3.5.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f9f8405c2c758532c74fed975dbee57be1f31a6e865c031870c79a6ed3212ada", size = 244070, upload-time = "2026-08-15T08:17:19.191Z" }, + { url = "https://files.pythonhosted.org/packages/f6/0b/c5292a2462d69b7378ea89793bbb5b2b6fcf6f7dd6d1667f9619094ad553/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:96fef3e886d6a9874b14f27fc193fbdc69d5d8035783d86aa4e1cea594e695f9", size = 240110, upload-time = "2026-08-15T08:17:20.547Z" }, + { url = "https://files.pythonhosted.org/packages/46/22/111e5be3b740d5c2a5bfcedb3d237b6591e5c2e82ae9d6ffcb121fe0909c/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5d8531a6569d025f68e2321e7638fb7978f23db58e5f69f56913837aae03816e", size = 232836, upload-time = "2026-08-15T08:17:21.895Z" }, + { url = "https://files.pythonhosted.org/packages/f9/d2/d2aad6fe0dbb44b194bf3becb60f5a0ac48446ade999a47fe7bb41eb09a7/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:aae2ee51122d3ae968a3837d97dc24a0aeebb0dea23694422cd172bd30017cd6", size = 262712, upload-time = "2026-08-15T08:17:23.727Z" }, + { url = "https://files.pythonhosted.org/packages/35/5a/337e4663a5eae6de99db940ee8066d4145caafb61327db62deda15313cce/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:7235dc28fc6dd9d832ac7c7bce95367dedb85929f17368a0c2bee1e080b9acbf", size = 242977, upload-time = "2026-08-15T08:17:25.157Z" }, + { url = "https://files.pythonhosted.org/packages/ca/85/f82f8a92e31c7519410e2e1afdc630f28ec47490ce2c09a11c1a43cbb459/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4abdc5f9ad448c1ecbfae2974b820535d6bc6e7eef63babbab3d81cf46968c71", size = 260207, upload-time = "2026-08-15T08:17:26.602Z" }, + { url = "https://files.pythonhosted.org/packages/b7/52/643d11ffd60e9ac2fd1fb87e167a19285b9eefeff4a40e63c87cbfbeab36/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ba501e667c17d8411f98e67a022d9604ef179aff0e459b7e292c796837c13573", size = 250562, upload-time = "2026-08-15T08:17:27.971Z" }, + { url = "https://files.pythonhosted.org/packages/62/16/46556278c2168d12df9da7fede5dc6fc70e60301b26a82bbeec238c9cfe3/charset_normalizer-3.5.1-cp312-cp312-win32.whl", hash = "sha256:cfa1c0cc3a8f9f53f1243a5a99ac36fd003880199383b37672e86ddda9cb07e2", size = 178507, upload-time = "2026-08-15T08:17:29.277Z" }, + { url = "https://files.pythonhosted.org/packages/9d/7a/4c6c298171e6b3e745633180ff59350fc0ca0db1ffd28df1e369e0579f71/charset_normalizer-3.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:3617ac3cfd8b9888f145ad89dd6e692285834b0201c6074a5eeaad3fd4d668c2", size = 200551, upload-time = "2026-08-15T08:17:30.668Z" }, + { url = "https://files.pythonhosted.org/packages/cd/d7/eb95a042f0dd22e304b0b6472b154f3546a1a039a9ee89ccb2a7f61591fc/charset_normalizer-3.5.1-cp312-cp312-win_arm64.whl", hash = "sha256:88e85ab89cb822c1e635f51d6d32e488f94e002e70e2f492bdb8b945543f345a", size = 180700, upload-time = "2026-08-15T08:17:32.028Z" }, + { url = "https://files.pythonhosted.org/packages/bc/61/2cb6ad133dbbb449fa2d37ccae973232f4827e799af258d15e589a3d1e9e/charset_normalizer-3.5.1-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:4f298bdadb8f0b9e5672877f647d1be9373ef5320c9e2f049795e26cad28b6a9", size = 211584, upload-time = "2026-08-15T08:17:33.597Z" }, + { url = "https://files.pythonhosted.org/packages/18/57/a305c968be1ca13f3dd1b32f445877e97addf55d80b65c7cb35fac82b777/charset_normalizer-3.5.1-cp313-cp313-android_24_x86_64.whl", hash = "sha256:88ca277405c2d3b71c4e1c2ee0e7966e807bcba86a69d11e19ba199d18ae4491", size = 223359, upload-time = "2026-08-15T08:17:35.022Z" }, + { url = "https://files.pythonhosted.org/packages/09/0a/d3646670292ce8d8f8cc11ac067d44885e697a5591f57a9221128da5e7b3/charset_normalizer-3.5.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:9362dd90aa7dab48c0054a21187791ccf05473f7dba5d92b8033ae62164675e7", size = 194464, upload-time = "2026-08-15T08:17:36.452Z" }, + { url = "https://files.pythonhosted.org/packages/de/93/d51ec556e01042fed6f993ea859311bc7917b466684182fbbceb6ca24762/charset_normalizer-3.5.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:977cdbd483a9cff38179bea4fd754289a6f2195c7abd414aba85410b3e66cc5e", size = 197676, upload-time = "2026-08-15T08:17:37.819Z" }, + { url = "https://files.pythonhosted.org/packages/a4/a0/562247944386f7d4ef94467e84876600cc1e0f1b93239aaa9213d2bc3cbd/charset_normalizer-3.5.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e90251c0c7bdd54a100a0dce3c07b7e637278c93af29dbf78ebb89a58c4bac7d", size = 340473, upload-time = "2026-08-15T08:17:39.303Z" }, + { url = "https://files.pythonhosted.org/packages/31/e7/1d994be1b93d41e9502b8b0460eaa88a1dd8df335df415db87d6c3e91ab2/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94d78ecec2605a8d0398b0f365d5f12a63248438516f5dac536a5eff7337df4a", size = 240156, upload-time = "2026-08-15T08:17:40.66Z" }, + { url = "https://files.pythonhosted.org/packages/09/53/27923ce5cc6cbccb832037b27dca98882d9c53e9b69e866bbbef4aae7fc8/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d59b75732e9b6f27388e10c14b0259cc5f2e48c78627d185e6a177b58ad3cffe", size = 228246, upload-time = "2026-08-15T08:17:42.003Z" }, + { url = "https://files.pythonhosted.org/packages/ce/48/5a97e84d63af1d55c07439cb80e56d99a8efb4295700eb4e18c0d1615d2c/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0d929fc574b4d6fd9e7c0f5c2ede8716a41911923aa7fa5fce38e0818aa4a1ac", size = 263660, upload-time = "2026-08-15T08:17:43.627Z" }, + { url = "https://files.pythonhosted.org/packages/7a/c2/071575791dcc88316c0a9a65ce38897a82e4cfe4a325f0f7fe1b1ac47bcf/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:394fea06235c8543390050ed5f529187074b029fb027213f6c46ac11ab5d950e", size = 260354, upload-time = "2026-08-15T08:17:45.094Z" }, + { url = "https://files.pythonhosted.org/packages/fb/af/63240b0c0248c075c2535a1f1bd992821d8251b9f173abc13329661d09e4/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62b55f6722735a6c472f88361cde6640608773d9443cebdbb51abf436a1fcdd3", size = 250638, upload-time = "2026-08-15T08:17:46.496Z" }, + { url = "https://files.pythonhosted.org/packages/4d/66/70dfad64f15be09c15ccfee81330a7e515895dbe296dd23114e9a231268a/charset_normalizer-3.5.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa48b1b63d639f9483e0633e092f5851e2348c352f1f9bb6c8182f87884ef876", size = 244583, upload-time = "2026-08-15T08:17:47.963Z" }, + { url = "https://files.pythonhosted.org/packages/c0/24/ef36367d38b9ddd4bccbf72888c342e8de1f5ae506fa0b2dcf970e2732a1/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c71fb0d56c920c269cd3e2e3fe7c610e3f1fdb21a6ce60efa6430ff63676cea6", size = 242038, upload-time = "2026-08-15T08:17:49.481Z" }, + { url = "https://files.pythonhosted.org/packages/db/ab/55e683ba0fff2e43adafc10daa3001eac90fdaa419a97227d5a7067eedde/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:485a0d363cafefcd2538a73c7c838daa2035f09b2c9f9b5e3133f80c6aeb84c2", size = 233677, upload-time = "2026-08-15T08:17:50.845Z" }, + { url = "https://files.pythonhosted.org/packages/bd/67/0f40eaf8d1b6e7cf15e82382a2965efaca787fc1c2794b7021d37aaf5036/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5c0ea61a470e070686aa30892fed79e297d2c8d0ab46b8bcdf027d38c51da591", size = 264491, upload-time = "2026-08-15T08:17:52.61Z" }, + { url = "https://files.pythonhosted.org/packages/5c/64/12b4c2a11ee8df4fcc518c78b0d93e3a92bd3d5253d1617ce74ff0e8c7ef/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:90b7481fb62fbe172c558bc6fd1c4c98d82004a54a7551f20e11ac9bf0b8708c", size = 245196, upload-time = "2026-08-15T08:17:54.023Z" }, + { url = "https://files.pythonhosted.org/packages/37/2e/651d910af6d0fba325eee1cda37ec5443462ed25360e666c144166eb6091/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:35fe081843b35aad20ffeccec3eeffbe637b15d14f3fb22cc1b59cd8ec17e93c", size = 261660, upload-time = "2026-08-15T08:17:55.491Z" }, + { url = "https://files.pythonhosted.org/packages/90/c6/b09e05e6db7f64338e0dc067c79577b1138da86c1e38369096851d96be88/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fd0350afdc3aabd5576f60ea109228bd5538139713c7b094c5cd27c73a98bc6f", size = 252618, upload-time = "2026-08-15T08:17:57.025Z" }, + { url = "https://files.pythonhosted.org/packages/76/4e/362d4f9fdcdf5556fb2aa3ce7d4a58ebce03ed1ff03aa1d9aca8d02f13f3/charset_normalizer-3.5.1-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:9d9a0dc7cbe9bec24c3f767c9122c41fe5a1bc43f47cd099d00d393e09769de4", size = 140362, upload-time = "2026-08-15T08:17:58.425Z" }, + { url = "https://files.pythonhosted.org/packages/b4/d4/703be739b26acce318bd29eb3b25b7209e1b1f527f9eae3d1f1f01fdde2b/charset_normalizer-3.5.1-cp313-cp313-win32.whl", hash = "sha256:d63600d620ad0064c3a748b950ac5ea38a80190e5498532efefa4b7b3f1da1f3", size = 177755, upload-time = "2026-08-15T08:18:00.037Z" }, + { url = "https://files.pythonhosted.org/packages/8a/33/56d97ade41c8db611e727168c52ae46c9224c362ec28d4b65d7e9869e8da/charset_normalizer-3.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:aea996a6aba25260827c9ea511d1addfde2da9eb686ac961838509086188b7e6", size = 199295, upload-time = "2026-08-15T08:18:01.506Z" }, + { url = "https://files.pythonhosted.org/packages/5b/75/5b20dd1e6573a01a08158fe104104fa2c8abf941745596954185726cd46c/charset_normalizer-3.5.1-cp313-cp313-win_arm64.whl", hash = "sha256:fd0a274c0e5f9a21565cd9d3dd749b61f96b7aa1e20a93aa1ba4029518f2e5c0", size = 179856, upload-time = "2026-08-15T08:18:02.929Z" }, + { url = "https://files.pythonhosted.org/packages/5b/97/fb4e82231aba271ffd775a1b4993b0defc4e3059f286ae41d9433409fe85/charset_normalizer-3.5.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:41876ee62a3dddf48ff1121ad8f0798032aa03f2fd35f21f34a4cab14f18d8d2", size = 331467, upload-time = "2026-08-15T08:19:50.959Z" }, + { url = "https://files.pythonhosted.org/packages/9f/2f/fe3f187327aac18e2d54e9d2b08e15d27bf9b642d9e51c219f130fc34d1a/charset_normalizer-3.5.1-cp37-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a6dac12ff6b846103483683f60c5f8fee205121adc58ffd87e90a90a3af69e99", size = 253057, upload-time = "2026-08-15T08:19:52.654Z" }, + { url = "https://files.pythonhosted.org/packages/d7/c7/9e48cee5c161fe24da823b61bf381921d77cb994a0a4de148e95018c1984/charset_normalizer-3.5.1-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cee5dd7c6fb5dd52a0fe2a740f9bc6e3593f5f8b1788bde49de02086f30182b2", size = 240930, upload-time = "2026-08-15T08:19:54.163Z" }, + { url = "https://files.pythonhosted.org/packages/49/e0/716601f3cc69be7b198951150c75ead1ece33c3c8036ff6ffa46029659a0/charset_normalizer-3.5.1-cp37-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:343fb4f2821043bd87095f7b08a1a181febc8e36ac64212143bbfd0a0e1bc235", size = 230822, upload-time = "2026-08-15T08:19:55.807Z" }, + { url = "https://files.pythonhosted.org/packages/d3/05/71bfc5caa0abcc45aea1f6a4d50ac68e59605ddc7666fe8494f4cd229665/charset_normalizer-3.5.1-cp37-abi3-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ae4a097991662cd4fff0ddc74e0fe7874f82e00042fa0ea00855645ed0c79598", size = 260037, upload-time = "2026-08-15T08:19:57.312Z" }, + { url = "https://files.pythonhosted.org/packages/c3/92/de7e32ed05341e7a9c4c877c318418197b7f2d66a3b68d561bf2ac57ca3e/charset_normalizer-3.5.1-cp37-abi3-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4b599739b93b2cbeded49645ae3c8d1405c29ddfbceac1545c87a3f9580a9e96", size = 255097, upload-time = "2026-08-15T08:19:59.056Z" }, + { url = "https://files.pythonhosted.org/packages/f5/7b/ade0a122600319dfa0b1000ab0f9731c94a817904cf3c5de408c73a4ede7/charset_normalizer-3.5.1-cp37-abi3-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b39b69b347e5e47a3b5b8cfc005c68c1ba347474e3960236c4944a8ecd174962", size = 250166, upload-time = "2026-08-15T08:20:00.612Z" }, + { url = "https://files.pythonhosted.org/packages/75/9c/019fbb9f4834491a160951349b1a3714439376f66e5f7cf18b4f18f0c7aa/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:a2028475ba855475b8b4d3cfeb4994269c967aea8b9892dfba907f4263a863a3", size = 241821, upload-time = "2026-08-15T08:20:02.321Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b8/11d4840bfc99330cc7fbcc2681ee5a044553a6e77655508d8f9b2bff7b34/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:36047af20e17097c3bb9476c2b7655f2f7aa51322c0ba58c07695bedf755a950", size = 232529, upload-time = "2026-08-15T08:20:04.008Z" }, + { url = "https://files.pythonhosted.org/packages/18/96/2b3a21492d9f65171ac75d872f5018260013d00bfa0ff70ec9f179148cbd/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:4c4fb141a727957c93edfe5c32a26ceb6b5f6461d67146e2d39f51e16170bea8", size = 260348, upload-time = "2026-08-15T08:20:05.877Z" }, + { url = "https://files.pythonhosted.org/packages/d6/aa/a69a2028e8bd052476c245460ab19d7de595de084dd968f2d75cd50c3e25/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:2f293479cce755c75f1697e87c409b7ae4c555c7dfecb6e988ad13abba943031", size = 247234, upload-time = "2026-08-15T08:20:07.487Z" }, + { url = "https://files.pythonhosted.org/packages/35/8a/3d130aeabcaf3d2466af76b7b141c08d9e89c9016ab4b7cdd0f7dc2d1c62/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_s390x.whl", hash = "sha256:3588e376b3ea2eea84976f67273d679f229e24c66dce7b82ae45aef04ff6e072", size = 256917, upload-time = "2026-08-15T08:20:09.142Z" }, + { url = "https://files.pythonhosted.org/packages/80/c2/a7379b840292d0c1ab9fbd17d1f3967aa81794dc95bc74be8999d7fedcf7/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e199fb99720074809a7720f1c0b4d919eea8b87e88713e0f8f602f7bef543d9d", size = 254846, upload-time = "2026-08-15T08:20:10.727Z" }, + { url = "https://files.pythonhosted.org/packages/01/65/d43b714731bb2f40d4053dfa00ecfc1c5a301f8e3316c5db3a09af59fe94/charset_normalizer-3.5.1-cp37-abi3-win32.whl", hash = "sha256:dd732602a7009217f658d5863d12d79d373a4de0eebc111094bcdd3bb8e0a6cc", size = 174216, upload-time = "2026-08-15T08:20:12.334Z" }, + { url = "https://files.pythonhosted.org/packages/35/4f/b911ed898b26a09789eba9c9200c999aff6c61b4bafaf4838e56d1a1e1a3/charset_normalizer-3.5.1-cp37-abi3-win_amd64.whl", hash = "sha256:70055ff39b97c99e7ae40ea3e393fb62aa2e44dbd9b29f8d14f42fb0025c3959", size = 199764, upload-time = "2026-08-15T08:20:13.908Z" }, + { url = "https://files.pythonhosted.org/packages/f0/a7/920baf467bfd9bf689f3b318340f37aee4572a71f162bd8db51da55ba4fa/charset_normalizer-3.5.1-cp37-abi3-win_arm64.whl", hash = "sha256:87e4f41d375c0b9be2fb5251aee4b8a689169e134535aed81bf085c3b647451e", size = 287318, upload-time = "2026-08-15T08:20:15.551Z" }, + { url = "https://files.pythonhosted.org/packages/cc/61/d01fc49b8dea277640b55a9e15960dbca9fdc8c9fde18e572d39c59f4019/charset_normalizer-3.5.1-py3-none-any.whl", hash = "sha256:6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6", size = 68658, upload-time = "2026-08-15T08:20:43.306Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "comm" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/13/7d740c5849255756bc17888787313b61fd38a0a8304fc4f073dfc46122aa/comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971", size = 6319, upload-time = "2025-07-25T14:02:04.452Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload-time = "2025-07-25T14:02:02.896Z" }, +] + +[[package]] +name = "contourpy" +version = "1.3.3" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.12' and sys_platform == 'win32'", + "python_full_version < '3.12' and sys_platform == 'emscripten'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" } }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1", size = 288773, upload-time = "2025-07-26T12:01:02.277Z" }, + { url = "https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381", size = 270149, upload-time = "2025-07-26T12:01:04.072Z" }, + { url = "https://files.pythonhosted.org/packages/30/2e/dd4ced42fefac8470661d7cb7e264808425e6c5d56d175291e93890cce09/contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7", size = 329222, upload-time = "2025-07-26T12:01:05.688Z" }, + { url = "https://files.pythonhosted.org/packages/f2/74/cc6ec2548e3d276c71389ea4802a774b7aa3558223b7bade3f25787fafc2/contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1", size = 377234, upload-time = "2025-07-26T12:01:07.054Z" }, + { url = "https://files.pythonhosted.org/packages/03/b3/64ef723029f917410f75c09da54254c5f9ea90ef89b143ccadb09df14c15/contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a", size = 380555, upload-time = "2025-07-26T12:01:08.801Z" }, + { url = "https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db", size = 355238, upload-time = "2025-07-26T12:01:10.319Z" }, + { url = "https://files.pythonhosted.org/packages/98/56/f914f0dd678480708a04cfd2206e7c382533249bc5001eb9f58aa693e200/contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620", size = 1326218, upload-time = "2025-07-26T12:01:12.659Z" }, + { url = "https://files.pythonhosted.org/packages/fb/d7/4a972334a0c971acd5172389671113ae82aa7527073980c38d5868ff1161/contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f", size = 1392867, upload-time = "2025-07-26T12:01:15.533Z" }, + { url = "https://files.pythonhosted.org/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff", size = 183677, upload-time = "2025-07-26T12:01:17.088Z" }, + { url = "https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42", size = 225234, upload-time = "2025-07-26T12:01:18.256Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470", size = 193123, upload-time = "2025-07-26T12:01:19.848Z" }, + { url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419, upload-time = "2025-07-26T12:01:21.16Z" }, + { url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979, upload-time = "2025-07-26T12:01:22.448Z" }, + { url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653, upload-time = "2025-07-26T12:01:24.155Z" }, + { url = "https://files.pythonhosted.org/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8", size = 379536, upload-time = "2025-07-26T12:01:25.91Z" }, + { url = "https://files.pythonhosted.org/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea", size = 384397, upload-time = "2025-07-26T12:01:27.152Z" }, + { url = "https://files.pythonhosted.org/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1", size = 362601, upload-time = "2025-07-26T12:01:28.808Z" }, + { url = "https://files.pythonhosted.org/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7", size = 1331288, upload-time = "2025-07-26T12:01:31.198Z" }, + { url = "https://files.pythonhosted.org/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411", size = 1403386, upload-time = "2025-07-26T12:01:33.947Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69", size = 185018, upload-time = "2025-07-26T12:01:35.64Z" }, + { url = "https://files.pythonhosted.org/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b", size = 226567, upload-time = "2025-07-26T12:01:36.804Z" }, + { url = "https://files.pythonhosted.org/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc", size = 193655, upload-time = "2025-07-26T12:01:37.999Z" }, + { url = "https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5", size = 293257, upload-time = "2025-07-26T12:01:39.367Z" }, + { url = "https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1", size = 274034, upload-time = "2025-07-26T12:01:40.645Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286", size = 334672, upload-time = "2025-07-26T12:01:41.942Z" }, + { url = "https://files.pythonhosted.org/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5", size = 381234, upload-time = "2025-07-26T12:01:43.499Z" }, + { url = "https://files.pythonhosted.org/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67", size = 385169, upload-time = "2025-07-26T12:01:45.219Z" }, + { url = "https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9", size = 362859, upload-time = "2025-07-26T12:01:46.519Z" }, + { url = "https://files.pythonhosted.org/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659", size = 1332062, upload-time = "2025-07-26T12:01:48.964Z" }, + { url = "https://files.pythonhosted.org/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7", size = 1403932, upload-time = "2025-07-26T12:01:51.979Z" }, + { url = "https://files.pythonhosted.org/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d", size = 185024, upload-time = "2025-07-26T12:01:53.245Z" }, + { url = "https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263", size = 226578, upload-time = "2025-07-26T12:01:54.422Z" }, + { url = "https://files.pythonhosted.org/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9", size = 193524, upload-time = "2025-07-26T12:01:55.73Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b3/f8a1a86bd3298513f500e5b1f5fd92b69896449f6cab6a146a5d52715479/contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d", size = 306730, upload-time = "2025-07-26T12:01:57.051Z" }, + { url = "https://files.pythonhosted.org/packages/3f/11/4780db94ae62fc0c2053909b65dc3246bd7cecfc4f8a20d957ad43aa4ad8/contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216", size = 287897, upload-time = "2025-07-26T12:01:58.663Z" }, + { url = "https://files.pythonhosted.org/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae", size = 326751, upload-time = "2025-07-26T12:02:00.343Z" }, + { url = "https://files.pythonhosted.org/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20", size = 375486, upload-time = "2025-07-26T12:02:02.128Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99", size = 388106, upload-time = "2025-07-26T12:02:03.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/52/5b00ea89525f8f143651f9f03a0df371d3cbd2fccd21ca9b768c7a6500c2/contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b", size = 352548, upload-time = "2025-07-26T12:02:05.165Z" }, + { url = "https://files.pythonhosted.org/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a", size = 1322297, upload-time = "2025-07-26T12:02:07.379Z" }, + { url = "https://files.pythonhosted.org/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e", size = 1391023, upload-time = "2025-07-26T12:02:10.171Z" }, + { url = "https://files.pythonhosted.org/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3", size = 196157, upload-time = "2025-07-26T12:02:11.488Z" }, + { url = "https://files.pythonhosted.org/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8", size = 240570, upload-time = "2025-07-26T12:02:12.754Z" }, + { url = "https://files.pythonhosted.org/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301", size = 199713, upload-time = "2025-07-26T12:02:14.4Z" }, + { url = "https://files.pythonhosted.org/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497", size = 278809, upload-time = "2025-07-26T12:02:52.74Z" }, + { url = "https://files.pythonhosted.org/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8", size = 261593, upload-time = "2025-07-26T12:02:54.037Z" }, + { url = "https://files.pythonhosted.org/packages/0a/59/ebfb8c677c75605cc27f7122c90313fd2f375ff3c8d19a1694bda74aaa63/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e", size = 302202, upload-time = "2025-07-26T12:02:55.947Z" }, + { url = "https://files.pythonhosted.org/packages/3c/37/21972a15834d90bfbfb009b9d004779bd5a07a0ec0234e5ba8f64d5736f4/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989", size = 329207, upload-time = "2025-07-26T12:02:57.468Z" }, + { url = "https://files.pythonhosted.org/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77", size = 225315, upload-time = "2025-07-26T12:02:58.801Z" }, +] + +[[package]] +name = "contourpy" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.12' and sys_platform == 'win32'", + "python_full_version >= '3.12' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "numpy", version = "2.5.3", source = { registry = "https://pypi.org/simple" } }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/5a/a55177dd22553a277388e8a1b3220e92de91bacb28356cdc73caa240121d/contourpy-1.4.0.tar.gz", hash = "sha256:20156f5a1ac4f8ce02656e39a61e82164a3d359796dc8026f75b062783d500e1", size = 13323726, upload-time = "2026-09-11T19:05:05.808Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/ba/01bde9753bdbba04a6da9d2bff3881f021bc708f654655e95fae26d3b3a3/contourpy-1.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:186ba929df36d61b6127da2e89cd1357e4cb79aca647381ab1a6feb0b152877b", size = 297302, upload-time = "2026-09-11T19:02:45.103Z" }, + { url = "https://files.pythonhosted.org/packages/dd/f5/c5bf67522d49a2222f3154fe46879451d26f0e35ece41770758a64ea78cb/contourpy-1.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c76f3a5318164db7d9401132fc1b5364b784c613c93fa506e3b5e6d1bf353ec8", size = 284921, upload-time = "2026-09-11T19:02:48.049Z" }, + { url = "https://files.pythonhosted.org/packages/0f/cc/cb989599eec12fda312e127eb8e04a8b21a7a6c94bf7ff1bc68273334a42/contourpy-1.4.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:43c3ccbb32c6294b183dcc8e8c46dacf5ecef809497e3d48a5be298eef185ad0", size = 356332, upload-time = "2026-09-11T19:02:51.408Z" }, + { url = "https://files.pythonhosted.org/packages/47/fb/6f620d7602507817b0b4c21dd790ed68688f1f4ae9c29aacf21f08db5cf1/contourpy-1.4.0-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:86d05cec773c9507a3950122e0e40ce77c23c75ceeb2fc189514e71893cbb34b", size = 405878, upload-time = "2026-09-11T19:02:54.093Z" }, + { url = "https://files.pythonhosted.org/packages/32/4e/693c6d6bdece679f0953775eef3a1b66d56be55478d936e7deb1f3004422/contourpy-1.4.0-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2deb580178ca19437a84bd77e4bc2cd91a8ccad212413a83c273900868b5978c", size = 408296, upload-time = "2026-09-11T19:02:56.528Z" }, + { url = "https://files.pythonhosted.org/packages/78/f9/b6831508960d559581c448532ba4df312217072975486dbf2b24fcc5b76f/contourpy-1.4.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:875f42444c9cf48d56f724f2637e60d0f73b3b12c9041e1484580a233edf9591", size = 383243, upload-time = "2026-09-11T19:02:58.638Z" }, + { url = "https://files.pythonhosted.org/packages/f2/21/52903825a0ae7bb625e8bd30a09816d4c3c5d6174a469c10a616166cf780/contourpy-1.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f863c6100bf926cf47d13f3cd75f9bb8ebd98aaab230eeb4468b91f98f39a6b3", size = 1357306, upload-time = "2026-09-11T19:03:01.036Z" }, + { url = "https://files.pythonhosted.org/packages/d8/79/d68b1ce8539e4071518fed9523f558398f34dcd078b8927b109c72dad2ef/contourpy-1.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3863ef2e2b13fe93f8c0ebb08ee400cb07153b8b0e91c5acb26e4537f283634f", size = 1427243, upload-time = "2026-09-11T19:03:03.866Z" }, + { url = "https://files.pythonhosted.org/packages/ac/f0/b75a10e9d0616b97a30de277b6dfe83f1879880854c7330337309530eb48/contourpy-1.4.0-cp312-cp312-win32.whl", hash = "sha256:5450f091ac1be0be3ad3a2a3b3f23b5e443e78c670ced4fd347d626f92a28fd2", size = 347345, upload-time = "2026-09-11T19:03:06.192Z" }, + { url = "https://files.pythonhosted.org/packages/50/a9/dab08786bb4d77ef9a046b3c1be923be4e73c5d07d91f5a54e8ea9b09e41/contourpy-1.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:6e697d94e69f499ff6bebb899cae97a58d5d14f0e1fe9568b43a0248d2f9af8c", size = 234083, upload-time = "2026-09-11T19:03:08.122Z" }, + { url = "https://files.pythonhosted.org/packages/47/b9/3ba509755a970dbde5948e7142ac21f266be72f38017cc4087a05fdceee1/contourpy-1.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:0c7a4c2716a4e98342221954416a836cca77c996c14ddbf22b5f01d5d93ca09c", size = 559521, upload-time = "2026-09-11T19:03:10.047Z" }, + { url = "https://files.pythonhosted.org/packages/b7/8b/62a6eacea08ea0b6ab0159a7783df7ed421ff9c1ff58fef7c31f58fa5e52/contourpy-1.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e21d1d4a9db5b3a793649c7ab0ddb4697f2818929eec871a7b9c45fce7b2a1ea", size = 297330, upload-time = "2026-09-11T19:03:11.809Z" }, + { url = "https://files.pythonhosted.org/packages/3f/2f/103cdc5b7077cd569989d3ddb99ee3d4e96ee31bde8df2a6e426b2dc6195/contourpy-1.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:196759a3e4db60e1546167e361090ebb6d199aa3aafc9e34ea17a5ac3b23e814", size = 285037, upload-time = "2026-09-11T19:03:13.781Z" }, + { url = "https://files.pythonhosted.org/packages/bf/25/97001d1fdf940e6f5adfc592d4f5899fff95daf7dceead3988fe09987d2d/contourpy-1.4.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c0e07c691f3b3321913ed9b8161c50ea5f77fadd006f52f5e755359b0dcbfc5", size = 356675, upload-time = "2026-09-11T19:03:15.374Z" }, + { url = "https://files.pythonhosted.org/packages/a6/5e/9a7241a89e2f74402aefa2569e1349ad2750ff77823c04c788eaaedb7fdd/contourpy-1.4.0-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7f861af508fca2384eef392bc1d8377cfa349b2b854cb11b45d89c75780e2561", size = 406990, upload-time = "2026-09-11T19:03:17.44Z" }, + { url = "https://files.pythonhosted.org/packages/36/81/3a4fbbf6a806eada5453a6d16f6c7d96b9f4b3e57a3127368fb545986b8a/contourpy-1.4.0-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a03b32c2e7eda8b17757c022162c13c86f5c3d6f937dddf9ba3c3ff7b513953b", size = 407271, upload-time = "2026-09-11T19:03:19.523Z" }, + { url = "https://files.pythonhosted.org/packages/68/77/8f93ecbde1a4d11dfd460cd19a0c159f5487352e751fa87f5d78cc9db08e/contourpy-1.4.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f1219a8898523cba821085f2da8a1b962cc696325763f09d7f93538ba43b2d70", size = 384707, upload-time = "2026-09-11T19:03:21.208Z" }, + { url = "https://files.pythonhosted.org/packages/05/07/e5cdf94d68961ee464de6b4fedd3d2f666584f59ccd124bb1290597122ab/contourpy-1.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:20da2f86bfaed60dbba729fe738c8241b1dd22b6cf7e8cbbf30df290bd04ba28", size = 1356741, upload-time = "2026-09-11T19:03:23.621Z" }, + { url = "https://files.pythonhosted.org/packages/fd/8a/2301d07accb257ac08daeb631875fada06fedd019c20ff7b00ee07e9d211/contourpy-1.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6ced1670fafee703b8277ab1645072a226e74f167166eae146fb743916119b67", size = 1426793, upload-time = "2026-09-11T19:03:25.955Z" }, + { url = "https://files.pythonhosted.org/packages/7d/5d/a62648f06259d15c139b14eb8cf3c58fe53cb970a55f2bb77d1070e80a41/contourpy-1.4.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:abd0f7e51ecc52bf8c95713bd80b1c17c516a71fa391c54475308a4377903c2b", size = 117961, upload-time = "2026-09-11T19:03:27.713Z" }, + { url = "https://files.pythonhosted.org/packages/71/31/c5b7771ba6982f319ec90c0cf5c425b36891adfeee2d9f667f90b2d0c166/contourpy-1.4.0-cp313-cp313-win32.whl", hash = "sha256:510f7d93d94cf6ebf4e2cd0640bea16ab8affac7547230175b6745b596ce0599", size = 347438, upload-time = "2026-09-11T19:03:29.829Z" }, + { url = "https://files.pythonhosted.org/packages/68/c1/a59df0754bf83a6f3e153cc19d550a5b01f607e389b1c4d57f436f9139e0/contourpy-1.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:6507a016976a75a15aee47809a34605de6244ccc056e6164bf9fb14b27eecad4", size = 234084, upload-time = "2026-09-11T19:03:31.657Z" }, + { url = "https://files.pythonhosted.org/packages/41/48/97224f5decb1efa5a610f912195deb45321f73ec9b9dac485cd6fe2d5a6a/contourpy-1.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:423bd5f4b3f11d54a8c597234e513382e3454bb106b8ec7ae32ba4ed63f8d99b", size = 559559, upload-time = "2026-09-11T19:03:33.528Z" }, +] + +[[package]] +name = "coverage" +version = "7.16.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/65/2d/c738872f477f5687152acae68635790387425d407ae37dd3d3a8a6692307/coverage-7.16.1.tar.gz", hash = "sha256:f83981779bcf9dfa06fa0a8d4cb43e0faec1706328ce07aa3e7b665b4ac0f210", size = 969651, upload-time = "2026-09-13T19:12:21.422Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/3a/d09495dfd5191b5593852bbe2f037afae768157443378d066d9ecea69a49/coverage-7.16.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72e013665e25cf9d44779f01f340af26319756f9a76822b7c94ce6b1d93813da", size = 223307, upload-time = "2026-09-13T19:08:44.914Z" }, + { url = "https://files.pythonhosted.org/packages/a3/34/310196a80258e28ebf6e5aa814a5a6ffbb18c03cf3c0c0c04191ed893e88/coverage-7.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cb05c0ff98b56ba6969adf35556bc43bcb8d094df8bc9cb403acff53460c4e07", size = 223817, upload-time = "2026-09-13T19:08:46.738Z" }, + { url = "https://files.pythonhosted.org/packages/73/29/ed0fda1fcd440cdfc07e72a07f3c9c3b43f65a6b3d53bff2cba9b9de50e8/coverage-7.16.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0d0ececb32090e3fbb03e0d352b973a0485879b4de6c58daf47227b9988b99e5", size = 254222, upload-time = "2026-09-13T19:08:48.358Z" }, + { url = "https://files.pythonhosted.org/packages/ac/4e/5e2507fbd71ec1047620978f39568b0d2ed6c4468d08495a0c24f5677f65/coverage-7.16.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f0ba3892d81aacf36996c52f16bca04e39af31a6c5de930b7688ab617f4a6475", size = 256134, upload-time = "2026-09-13T19:08:49.926Z" }, + { url = "https://files.pythonhosted.org/packages/7e/b1/a9f97846554bc240473656f9c3874591105f29c08eccf4282daadc6bc281/coverage-7.16.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a6410b75fe07d5271eaa95fc24bd0a9177ed588d9d1c10c0cf67829adb8f0567", size = 258240, upload-time = "2026-09-13T19:08:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/a0/c3/2b1ab208d06719394851cdd7dc322157870a93b178410b1bda6cac7755f9/coverage-7.16.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d1039cb2de093225d597109342ce1675626bd127565e80b3044f4eca07c15b2e", size = 260202, upload-time = "2026-09-13T19:08:53.204Z" }, + { url = "https://files.pythonhosted.org/packages/af/14/ff4db31d6e3126d5b72aab1e868d35ec94e1b71dee46f5c3b54cb1b2438e/coverage-7.16.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cf047bc39fde5425be2628666d0f435ed8817859111c3aacc84b32d858069f5d", size = 254305, upload-time = "2026-09-13T19:08:54.833Z" }, + { url = "https://files.pythonhosted.org/packages/ce/27/c28faa4818f61c49ca3bfb4a77e1c191e79a40447504b89af0bd859cd6fc/coverage-7.16.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2c05913d0d5badf7ac83200f35dcf9514cce5df16a7cc89e7d1d7fff0461813b", size = 255935, upload-time = "2026-09-13T19:08:56.453Z" }, + { url = "https://files.pythonhosted.org/packages/46/5a/42e64e5b716048cae33e2e15f8c6fe04a927467056c533b8e88900da895e/coverage-7.16.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4027bf6d7bc0a16df058ce913b69f10c5687f8e1ca668f08caa659ce101744bf", size = 253995, upload-time = "2026-09-13T19:08:58.159Z" }, + { url = "https://files.pythonhosted.org/packages/84/e5/860287acd5a1e29acd337f302b476b54148203590091b1a1555b2e914b50/coverage-7.16.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4f48b345f831eaf4402ab6333c2dc3e2e2b5bc7b9c1b8fe12680dee3f0538f01", size = 257767, upload-time = "2026-09-13T19:08:59.958Z" }, + { url = "https://files.pythonhosted.org/packages/a5/c5/4b68006da567b4b413352f891776c35776b3557a0479a28187ab57c21659/coverage-7.16.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:8643baeb590726c558b2faed6cd59b0917480f9367fcc692026f1a86d824fd08", size = 253715, upload-time = "2026-09-13T19:09:01.778Z" }, + { url = "https://files.pythonhosted.org/packages/a1/0e/b2d0c47cfbf11770e197f1d0f11a92864eb29fd7eaca45bc9915573d9725/coverage-7.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d06dcc420b570bf683cdb647cc8fe62b672d9e429ef711c3cbbb7a6880ca1572", size = 254624, upload-time = "2026-09-13T19:09:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/2e/14/3bab8821b2b942155578fc34e88e21b0670d922f039ab23651f6035ba7f7/coverage-7.16.1-cp311-cp311-win32.whl", hash = "sha256:946f58aa59b08bcd6afcc6a7bd0ff54ed5eee844f32ad69fe6814836d15856a2", size = 225404, upload-time = "2026-09-13T19:09:05.174Z" }, + { url = "https://files.pythonhosted.org/packages/9b/ce/4f4ce667a97d1c538b46a79b89161395ad2beffc248b6c782afc9f521927/coverage-7.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:684c7ee9b4c04358fe6ac8b517ab51ec35fcd79d08ff0f105dd8bcd96885bbb7", size = 225879, upload-time = "2026-09-13T19:09:06.81Z" }, + { url = "https://files.pythonhosted.org/packages/26/17/f3dce5e47351ab34522dd037fd64b111742958e24861bdd2820971bc1a26/coverage-7.16.1-cp311-cp311-win_arm64.whl", hash = "sha256:1b24f79e25bcf6c73931aeca7a3dfc7595c0cb5e9364aba3fdf387a3de4b1c22", size = 225428, upload-time = "2026-09-13T19:09:08.502Z" }, + { url = "https://files.pythonhosted.org/packages/1a/f7/7cd4c9f2a3b7574414222ec425d5eee21cc690d867a013315e3be8ba185c/coverage-7.16.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b7f2c26ce6ce0b1e0ca0d5fae96ea510e3a2e78b7207f06e76b7f2c87fa3d0af", size = 223475, upload-time = "2026-09-13T19:09:10.145Z" }, + { url = "https://files.pythonhosted.org/packages/3e/f2/9ac65f9cedd43f91e2d3657c11f13aef82aebae89b2243dc9e44fe58a740/coverage-7.16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070acb9da788dff743a4d36fc015feee12d68f0349959017542017c79f59c21c", size = 223845, upload-time = "2026-09-13T19:09:11.988Z" }, + { url = "https://files.pythonhosted.org/packages/62/4d/f13db452d4367fe1122abfd98ae330596f65a3b40498f8e1a5811f68f123/coverage-7.16.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e366587b370bc9b8b51b7b7272c610c56db5d5b4795b9e4a29d28ff2f440f809", size = 255341, upload-time = "2026-09-13T19:09:13.708Z" }, + { url = "https://files.pythonhosted.org/packages/5d/6b/85ed86e82835a96ddfbe7705c387c28ce1cbbecd1b6d606f5ddfeeb712df/coverage-7.16.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e82e10b9d290f60b63459cfb245a841aec347603997206296b93881463a93dcf", size = 258078, upload-time = "2026-09-13T19:09:15.368Z" }, + { url = "https://files.pythonhosted.org/packages/cd/d2/f66945853d850b9c05f4e012e37396f1f31d0cd40d062394b229c22e7b56/coverage-7.16.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3d73bb1f85c4150ac208fb0755beb04b2e44897bad81414de9380f98dd74729f", size = 259191, upload-time = "2026-09-13T19:09:17.046Z" }, + { url = "https://files.pythonhosted.org/packages/77/a1/7b907abe62461f289035c7ac60ab3e6334efb8c425151aac4abfa0c97820/coverage-7.16.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3397b9032553d281ad6a9253b12675b65e0cc8cd7a3b0633cf48872c9eb13360", size = 261452, upload-time = "2026-09-13T19:09:18.756Z" }, + { url = "https://files.pythonhosted.org/packages/51/e6/e26f4d6b1069a2a2fee3238a132f85c5b4c1dc25aebd88e015451ff0bd68/coverage-7.16.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:77890395cf37026a5907d3ad32376aa51f41c0f163b7477fdbd4f94966cc1d08", size = 255698, upload-time = "2026-09-13T19:09:20.786Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ec/99db7450e813050ebce300e31bbd4f997c76a8c6e3a6d168c5dffc104109/coverage-7.16.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b0944dc3bee3091039bf970d73caaf930c906013128a421bdc132e797494d941", size = 257111, upload-time = "2026-09-13T19:09:22.693Z" }, + { url = "https://files.pythonhosted.org/packages/2e/9d/500df9d3cd8c541ac84b5e0bcab00646be75654e05aa34e8410ec851282d/coverage-7.16.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b89d22a89d5bc05dd95b64e08295b8394aa96dc88e08f8ba210c9ebfebbe0489", size = 255258, upload-time = "2026-09-13T19:09:24.429Z" }, + { url = "https://files.pythonhosted.org/packages/c0/24/53318d96da332bb4946f8ac646fa19fd37fecbd0c49144735c716ac69bf0/coverage-7.16.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:550a2a1faf7559f13d5344f12d1eb886ad87955155d7dfab2a3fe5c8ec8fe776", size = 259326, upload-time = "2026-09-13T19:09:26.32Z" }, + { url = "https://files.pythonhosted.org/packages/c5/ce/abc0462b2e6ae96ae22197d2bc30fe33b6b4e52937e782745436ceb2a761/coverage-7.16.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:55eb268e5b81aefac759766c9162625b06c1bedb7b77d936225bafc4f038a6f6", size = 254827, upload-time = "2026-09-13T19:09:28.191Z" }, + { url = "https://files.pythonhosted.org/packages/8b/e1/0a04eedaaf19196b51f0180968134228c7646e469ed29914e48690a7cf3e/coverage-7.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:65a8fc80898c9ce59f04349fe8b4849b1f9787f14e52ead990e5f849ff4727a0", size = 256698, upload-time = "2026-09-13T19:09:29.922Z" }, + { url = "https://files.pythonhosted.org/packages/de/1d/d441a55cf22ce9d8e9e34814806c47441ab844bd534e0f4b64e1c6ae8bd1/coverage-7.16.1-cp312-cp312-win32.whl", hash = "sha256:528a61be40977c340cf201d23b69bd6a6bab507da60e9dbda85f8b30e935d70d", size = 225541, upload-time = "2026-09-13T19:09:31.752Z" }, + { url = "https://files.pythonhosted.org/packages/73/27/ec3d032375735dd331477caa051419678079ff90fcb53d0284a6c2bfb757/coverage-7.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:d0f02c633630e2b74522108ee95a84ad6e1204a8016a6cca5297f335ea27147e", size = 226075, upload-time = "2026-09-13T19:09:33.556Z" }, + { url = "https://files.pythonhosted.org/packages/94/00/90e9f5c4434878494306b9c0ee8068ebbd829483737d8cefccc58884d728/coverage-7.16.1-cp312-cp312-win_arm64.whl", hash = "sha256:2959978f9d1d20a2c0c15d0a68baaeccf615ac1aa214cf4a05a10d6f568926c8", size = 225461, upload-time = "2026-09-13T19:09:35.48Z" }, + { url = "https://files.pythonhosted.org/packages/aa/74/c08c0c4dc9fa6bcd1d90728a63660aa1b17b488a806948598456c48f75d1/coverage-7.16.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ee5465db6e9152a7d09f3215309326878c6aa3ac509195a369f9d264ff4bfbd9", size = 223501, upload-time = "2026-09-13T19:09:37.276Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c8/784986d326663285258a8e39835c46fb730cc85284f0dbcd82078586dd22/coverage-7.16.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2b8256f8b525ba233d2e4cdcdce0d6673c66fc9bf70df1fd5e67c54a74e2d245", size = 223876, upload-time = "2026-09-13T19:09:39.385Z" }, + { url = "https://files.pythonhosted.org/packages/15/76/73fb792928872bbb07e553f920ff55c65ee962c469265feb5d1d4ae5f97a/coverage-7.16.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d57cc400275b9a2892e905fc893f732b21ddb95271bf96406c88e2f6367848b5", size = 254863, upload-time = "2026-09-13T19:09:41.326Z" }, + { url = "https://files.pythonhosted.org/packages/ca/8d/1fd78899513244b065ccecdd1cfc6aa8b8f1bdee796d8c4f2aa8e8e5397d/coverage-7.16.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6b3fd0f3435ebb7a7183b32a6062a8b755f08242ced1f3f22761d30b56b3c2a5", size = 257460, upload-time = "2026-09-13T19:09:43.086Z" }, + { url = "https://files.pythonhosted.org/packages/47/1c/b23ddfcb7ef9bd7b3fdb7be9a5dccf9925ae88e556df7aa5b655283c78f2/coverage-7.16.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e5eb1762e7eb5fad34ef913e8107c7788a66f19d328e598ce95bf7217f9e5c8f", size = 258697, upload-time = "2026-09-13T19:09:45.161Z" }, + { url = "https://files.pythonhosted.org/packages/1c/c9/19d0c6ca35778a7e9415c30c46a0c64c9d4374219d004a35563132296896/coverage-7.16.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:46cd3a73e9140410de62cceb66214bce0e08fb3922b9176fbfc1522fec151b41", size = 260827, upload-time = "2026-09-13T19:09:47.061Z" }, + { url = "https://files.pythonhosted.org/packages/97/fc/5862f7344382c62b85df43d483e579168cc062e007f54d895dfa51fe3e7d/coverage-7.16.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d1ba5142d68dd2cb775cbd0ac8601819298152047803c8efe4eec6d7d7aa7878", size = 255038, upload-time = "2026-09-13T19:09:48.945Z" }, + { url = "https://files.pythonhosted.org/packages/2e/9f/5c26583199a68df8d15124b4590520903f8eb7cef17db293fea712bb0783/coverage-7.16.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c389c6f9d1d518e1249ddcb8a7f158135644ce2c508fa6cc17b680777dad5bf2", size = 256827, upload-time = "2026-09-13T19:09:50.738Z" }, + { url = "https://files.pythonhosted.org/packages/95/13/605198bff079b107336710f28a797312ab132587168600d70a290e7ecd2e/coverage-7.16.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cdc57746c7ac0ea063351b4d651c3bb4dd4fd35e64dbb8e90c10e14eb03c4080", size = 254794, upload-time = "2026-09-13T19:09:52.577Z" }, + { url = "https://files.pythonhosted.org/packages/43/b7/0bbb32dc5ccdac766a13763fdfbffd7d73fc80349a69230c46c6b71e7508/coverage-7.16.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5597180ed7670cc94c04c65347418a467d3a43d5f0cf52fcac647f5425f42037", size = 258947, upload-time = "2026-09-13T19:09:54.372Z" }, + { url = "https://files.pythonhosted.org/packages/13/bd/65c31ddd43ff4e61b63721b3dad17cca412dba6e2ce89f92abdf75734339/coverage-7.16.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:a9647a0ac46255b8fef59a433a2161f03e5483f3a35e1cbd9dfe4600baff0c6b", size = 254613, upload-time = "2026-09-13T19:09:56.198Z" }, + { url = "https://files.pythonhosted.org/packages/25/20/d278115f2ba522b3e3128c6852be265f4e0df7202b2effca4db96cf0217d/coverage-7.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e306e98186b9cd109121f3583aeb7978797ad21d948f22944c5c08845cd554d0", size = 256388, upload-time = "2026-09-13T19:09:58.095Z" }, + { url = "https://files.pythonhosted.org/packages/e1/ca/d43aa396fb3a2f71c9411b99d926475f5acaf5c124f605c592865c80c8d5/coverage-7.16.1-cp313-cp313-win32.whl", hash = "sha256:48a78a66fcce49d7f6156524bf979c0ac633d584199717c68c6ffa949fc14e6a", size = 225550, upload-time = "2026-09-13T19:09:59.998Z" }, + { url = "https://files.pythonhosted.org/packages/0e/30/df2f6114f6a17cffe94721bd1d298f77f86aad493717fa5bc03cb291a1a6/coverage-7.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:7af03247d598a353bbbbe1b925deb735276e4d845e7197c4073dc89352b236fa", size = 226091, upload-time = "2026-09-13T19:10:02.331Z" }, + { url = "https://files.pythonhosted.org/packages/ee/31/6f90d8aab72a112492bd50e3b5485b53b772b1f5fa70da0a620e723caae6/coverage-7.16.1-cp313-cp313-win_arm64.whl", hash = "sha256:166adae25b05b04c9a84135912066d9c97482115af38df1a419a38aacc6b6f5d", size = 225481, upload-time = "2026-09-13T19:10:04.151Z" }, + { url = "https://files.pythonhosted.org/packages/96/1a/d6d16babd0a5fe4c3fae40702158c570351694e74516d8d81b86c5637448/coverage-7.16.1-py3-none-any.whl", hash = "sha256:3d8bd4e58b6a5c2018d808f297905393c6c61da466a48c3f0596a76a4900ebe4", size = 215264, upload-time = "2026-09-13T19:12:18.895Z" }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version <= '3.11'" }, +] + +[[package]] +name = "cycler" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, +] + +[[package]] +name = "debugpy" +version = "1.8.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/44/9d/3cb6693342acf96802dba89934a5b8da43c201d764ebd1f2c0514a3d42bd/debugpy-1.8.22.tar.gz", hash = "sha256:e489c7268e1c7b41e13b438d9c533d2a7af73fb59bf8cd30fead8286c1c39c4e", size = 1710877, upload-time = "2026-09-15T21:44:02.578Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/4a/8c24c588088c622df6dacdc0110e9cc81b44781fe7a408113441e76aa955/debugpy-1.8.22-cp311-cp311-macosx_15_0_universal2.whl", hash = "sha256:66e4ac3d6e7026e83e7d93d7ee2f51dd4a4e8dff673578d424e60796893e5b2c", size = 2217799, upload-time = "2026-09-15T21:44:11.57Z" }, + { url = "https://files.pythonhosted.org/packages/c7/14/1c9ff33eba51da70a8dfe2277cc13153bb3ffec79282b9acfcdbe1641d30/debugpy-1.8.22-cp311-cp311-manylinux_2_34_x86_64.whl", hash = "sha256:192b73e8d53bbd60225220c0943627bf249ac93d0ea3090e23c45f3e0ceb6a35", size = 3074375, upload-time = "2026-09-15T21:44:13.349Z" }, + { url = "https://files.pythonhosted.org/packages/10/e8/1fa16a94af7d8b86c3ca336d7d32b78cb2c475266d0bb889732d2bc50310/debugpy-1.8.22-cp311-cp311-win32.whl", hash = "sha256:745e1800ec2961e5660c1a317c0a20e28c0fef4de36c04f17a21c33f2b37a92a", size = 5258392, upload-time = "2026-09-15T21:44:15.182Z" }, + { url = "https://files.pythonhosted.org/packages/32/1a/c086b883a4561017bfdd83c1bc70bf2b05ab6540ff767dedf207cadab938/debugpy-1.8.22-cp311-cp311-win_amd64.whl", hash = "sha256:1e76339d5510bc17e9181dba9577508afcb21aad5728f1a55ef74d7d97d255f3", size = 5277955, upload-time = "2026-09-15T21:44:16.986Z" }, + { url = "https://files.pythonhosted.org/packages/73/21/5c7f5c66eaeee57c9dadb0bbff22efddc8d99cdbd3d036c806175f1828cc/debugpy-1.8.22-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:4ad076f4f66cb8acb79e4384d48b1ea60a0b1957aa0b1112d4887ea3a4df60e0", size = 2499375, upload-time = "2026-09-15T21:44:18.478Z" }, + { url = "https://files.pythonhosted.org/packages/7e/ec/7389798843643ea5bc6a08480ba1b855377c70e2ed90189c0a03594e401e/debugpy-1.8.22-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:8a697acec45dbc70d17fb5d9f4f61989fc294d273c69de487fd10cb35fdd75eb", size = 4000941, upload-time = "2026-09-15T21:44:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/20/f4/64ce7a2499550929e08654360b270409eeda3e321b7c27027d9c919aa36b/debugpy-1.8.22-cp312-cp312-win32.whl", hash = "sha256:12bc7f368182b517cf26c76a2393fff65354e365fa1552b6241e66edff17997b", size = 5359040, upload-time = "2026-09-15T21:44:22.218Z" }, + { url = "https://files.pythonhosted.org/packages/4b/fe/e7d3b72874cdd327bda295d1995a01e426857ae9cbaaba74fd997bc3afbc/debugpy-1.8.22-cp312-cp312-win_amd64.whl", hash = "sha256:371a4ba4a5975eb958393903f3254cf983da7b1c7c178b3f987ee427f42515e3", size = 5398304, upload-time = "2026-09-15T21:44:24.119Z" }, + { url = "https://files.pythonhosted.org/packages/6b/f4/fee6d40f5865aa84e1100c9df1a0f2cf8991776b61f11f433ff277df4415/debugpy-1.8.22-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:c21dd7e1ec22556bb41dc3bf6b86c603e440ec889c4acb27d7206354b2106c54", size = 2493531, upload-time = "2026-09-15T21:44:25.835Z" }, + { url = "https://files.pythonhosted.org/packages/bc/4f/8df91270afbf61fc5ab202951f28451194a7eb093704b26da11cb0ecd308/debugpy-1.8.22-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:c1ffb9953708b648ecf6acd2e5ad2c002bf68785ed618197dd4463a2a7226f39", size = 3994351, upload-time = "2026-09-15T21:44:27.31Z" }, + { url = "https://files.pythonhosted.org/packages/4f/11/2e34a4f21d6155b0c58003fd6fca9819df7d6fe7d7acd83b146b648a57ee/debugpy-1.8.22-cp313-cp313-win32.whl", hash = "sha256:ba810a66b437e3c43ca0ce0892404f010338286263ca8e5108442d76a9485337", size = 5359071, upload-time = "2026-09-15T21:44:29.064Z" }, + { url = "https://files.pythonhosted.org/packages/d0/f5/c2b3e8260388d7b76bc4e5a3a29648a0ca47dca6a2721d6549ff2d944eee/debugpy-1.8.22-cp313-cp313-win_amd64.whl", hash = "sha256:f49b1d6cecf326b63c06d7f517e4a6642777f758c58cb799e7bc5a6dd74721c2", size = 5400362, upload-time = "2026-09-15T21:44:30.857Z" }, + { url = "https://files.pythonhosted.org/packages/56/3d/c7dc9f35bc9e22cdb53679f844bee40fd5cff871862f60595869a433400d/debugpy-1.8.22-py2.py3-none-any.whl", hash = "sha256:a9e9d3550e15ca479c59333e90845029190531f0cacfedab3b815a57bd913947", size = 5374857, upload-time = "2026-09-15T21:44:54.454Z" }, +] + +[[package]] +name = "defusedxml" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520, upload-time = "2021-03-08T10:59:26.269Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" }, +] + +[[package]] +name = "distlib" +version = "0.4.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/02/bd72be9134d25ed783ecbbc38a539ffaefbf90c78418c7fb7229600dbac7/distlib-0.4.3.tar.gz", hash = "sha256:f152097224a0ae24be5a0f6bae1b9359af82133bce63f98a95f86cae1aede9ed", size = 615141, upload-time = "2026-06-12T08:04:52.847Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/08/9c41fb51ab5b43eb21674aff13df270e8ba6c4b29c8624e328dc7a9482af/distlib-0.4.3-py2.py3-none-any.whl", hash = "sha256:4b0ce306c966eb73bc3a7b6abad017c556dadd92c44701562cd528ac7fde4d5b", size = 470628, upload-time = "2026-06-12T08:04:50.506Z" }, +] + +[[package]] +name = "docutils" +version = "0.22.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/b6/03bb70946330e88ffec97aefd3ea75ba575cb2e762061e0e62a213befee8/docutils-0.22.4.tar.gz", hash = "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968", size = 2291750, upload-time = "2025-12-18T19:00:26.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl", hash = "sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de", size = 633196, upload-time = "2025-12-18T19:00:18.077Z" }, +] + +[[package]] +name = "executing" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488, upload-time = "2025-09-01T09:48:10.866Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317, upload-time = "2025-09-01T09:48:08.5Z" }, +] + +[[package]] +name = "fastjsonschema" +version = "2.22.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/33/a4/9473c7c3b87009d9c1d74034e4a0f6a35ff0d42dd0f9866d0c3ec4e9217b/fastjsonschema-2.22.2.tar.gz", hash = "sha256:72064e12356a7d6ef02165be2946b9abadbdf238536e07eb587e3dbaa33099cf", size = 385171, upload-time = "2026-08-15T19:47:08.853Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/82/2755c7c982086f00d4dab85bc120ec35045a9fc2191893a6ce79afe94443/fastjsonschema-2.22.2-py3-none-any.whl", hash = "sha256:0fb3915616adac85ccfdd737d26be1089845d2019819505b42d39888458f74d4", size = 27413, upload-time = "2026-08-15T19:47:04.406Z" }, +] + +[[package]] +name = "filelock" +version = "3.32.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/59/e19834834cb01a32febfbb0f8a23a9088088f5d45991824ff2bc3b5e8acb/filelock-3.32.7.tar.gz", hash = "sha256:37b8a3d9811b0f9aef7e5ec5c71bb320de52df51e6ca9bcd6f5ad81187660da7", size = 225154, upload-time = "2026-09-16T00:24:20.907Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/15/df/31098c5aeb4d966b553641472bd55fcf5fdfac953549894b8a765ba44e91/filelock-3.32.7-py3-none-any.whl", hash = "sha256:65ff0d0190ea42038b32bda4b77834fb05be2cad4c5b9b01aa4dfb3614536e52", size = 100157, upload-time = "2026-09-16T00:24:19.543Z" }, +] + +[[package]] +name = "fonttools" +version = "4.65.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/77/51/d63c7e52163ac14393a35bd14bd7c0da95f8f74be5d7cc988092f9965129/fonttools-4.65.0.tar.gz", hash = "sha256:762ba5431358d0dbd4a01982484a1d494fb267e91f974cdcf20b80eab8560f6f", size = 3674467, upload-time = "2026-09-10T15:35:54.955Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/9e/58250cdc54d96fcfacb544e12997a6390fa4e6b71ae2241cfcfe5b341803/fonttools-4.65.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:06273c71e692caf5989c0437ca50875a5e49e216ddf653228fe9bb35bdc82c0f", size = 3089141, upload-time = "2026-09-10T15:33:24.509Z" }, + { url = "https://files.pythonhosted.org/packages/3e/67/0f0416069e38da0a1327a847a2e8dd1edb425d0043d8a3e63eb940070209/fonttools-4.65.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ca2b02d74e9ad7e21a1d11e4701425800a4b0c63cf90486e60258262feccbcbf", size = 2584298, upload-time = "2026-09-10T15:33:26.598Z" }, + { url = "https://files.pythonhosted.org/packages/99/0d/7e40e9957359afc0bab081131c215370a6d2d203361bb6f945ab595e924c/fonttools-4.65.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7830e9fa3bebc44dbc27ff44d8201def30ea5c48a773696d58e69e6bcd9cd5d4", size = 5498163, upload-time = "2026-09-10T15:33:29.071Z" }, + { url = "https://files.pythonhosted.org/packages/a1/e6/e48cf0a272a5d4d17a09d44f92727e67f975ddfa94acc8464763d19a654d/fonttools-4.65.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a3991732c87b3f054a2a8cf86dd0d602833fa8cb37c911503173771646e1013d", size = 5457456, upload-time = "2026-09-10T15:33:31.918Z" }, + { url = "https://files.pythonhosted.org/packages/e4/8a/a5c67ddeda82ee5e4ec3bc52ac1cbb685f0bb7a0516badc55643b454ab0d/fonttools-4.65.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6031e77b3fb8c765055ba2b8bd8dcb17030f3bf2484c448b472fdedf4460ba80", size = 5464334, upload-time = "2026-09-10T15:33:34.605Z" }, + { url = "https://files.pythonhosted.org/packages/d7/16/294e77383b2d39c9f8f25144a7ba23fe1cbbc05227cc72545097785ff07c/fonttools-4.65.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6813cc1e2e883bd6c15b3e04f72c78dc65fdc4ca861063adf5f341fbaec2ca62", size = 5595597, upload-time = "2026-09-10T15:33:37.591Z" }, + { url = "https://files.pythonhosted.org/packages/80/01/8e74ce8626c734959c782f2d89af8e9f14d078fd3d4ddf8b5a51401ae475/fonttools-4.65.0-cp311-cp311-win32.whl", hash = "sha256:4a5db8442453da4b6f43ad325879381b726bf2238a2253efd9584be21a2cefc2", size = 2441114, upload-time = "2026-09-10T15:33:40.592Z" }, + { url = "https://files.pythonhosted.org/packages/37/3e/835dc6c658426e2670b7f38c38295492fcbaeb06080e9dce89ce8105993c/fonttools-4.65.0-cp311-cp311-win_amd64.whl", hash = "sha256:9f201796c8e24e657be77c16fa664e798a46122144217f90838982937a964f0a", size = 2498823, upload-time = "2026-09-10T15:33:43.402Z" }, + { url = "https://files.pythonhosted.org/packages/58/db/242fa4fce7f632c5f7ab15585343393b25792510c0c32bd218ad24d59f1c/fonttools-4.65.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e844a45c9e5ced6536f184cf1a65b5d65e8f7e711993b413e10500a8223622e5", size = 3097120, upload-time = "2026-09-10T15:33:46Z" }, + { url = "https://files.pythonhosted.org/packages/a0/b6/42fa4d373416675f74446421cf0b2badb82a4245c60745f05f424f75c649/fonttools-4.65.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b30e953de049bf43fc0a63c7d0c44d205c923e4bbf24716aae1518c0e65f977c", size = 2584658, upload-time = "2026-09-10T15:33:48.473Z" }, + { url = "https://files.pythonhosted.org/packages/75/6f/d589b9d62280a846c77a2c383d852c6dcb79ae8aa02bf0fa46c8577af145/fonttools-4.65.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09c34bdeed8915bfb53bee0c8ed2254dbd8ec69c0014b7f3702f347c049bf358", size = 5425737, upload-time = "2026-09-10T15:33:51.473Z" }, + { url = "https://files.pythonhosted.org/packages/b5/09/de2c0c20a42c18e565a2617932beb08c06697bbdd0d3f62b108262e11583/fonttools-4.65.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:05595385ae99f4b9626cebb973bf171b8fe38a8f40708e6e42abba0ed7537778", size = 5402463, upload-time = "2026-09-10T15:33:54.907Z" }, + { url = "https://files.pythonhosted.org/packages/79/2e/bc0f5c9dce21821454bb5812d3b23410bca33c8bbd5468386d0327aa0cff/fonttools-4.65.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d95b34dd68fbfc0e4a1740c421597656117f979ed8dc85de66e08f9f9981806e", size = 5362168, upload-time = "2026-09-10T15:33:57.481Z" }, + { url = "https://files.pythonhosted.org/packages/1f/0d/2116763ade7e71e0e5d421babe1785d745be9b3d605bf914792ce1c97f79/fonttools-4.65.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:924d06e6130429168318db71c40174a765ad016fc4b56ca811287e3d7373b3a6", size = 5524117, upload-time = "2026-09-10T15:34:00.021Z" }, + { url = "https://files.pythonhosted.org/packages/e2/5e/f9600553b9f645e3068553831685ff1dab6259536a23b38d2e048de38f17/fonttools-4.65.0-cp312-cp312-win32.whl", hash = "sha256:04f73dd01005752a6e75cf4a8dc6b70dc724d1d4bc34cc89522153f4a2f07680", size = 2432089, upload-time = "2026-09-10T15:34:02.803Z" }, + { url = "https://files.pythonhosted.org/packages/3a/02/e436a6a1863b9862bab9f82d6da33055dd7aa3738017edd902a163525dc2/fonttools-4.65.0-cp312-cp312-win_amd64.whl", hash = "sha256:3b5d9ba89edf778b376e669b879ae33a198bf45cf5a23c3f6514f935cf9d0d9d", size = 2483475, upload-time = "2026-09-10T15:34:05.09Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5c/343a4225e83eb06f82c1d8bf41fc5e5f71eab2f62bc7ca215c764722c0a9/fonttools-4.65.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8b7bb52817a24731d2e4f4df0e71fdde05e6c806c8f8f1517b015d142fdacfa5", size = 3094663, upload-time = "2026-09-10T15:34:07.235Z" }, + { url = "https://files.pythonhosted.org/packages/9b/c9/49b2401be932741d9218181c08948c96db32eab21ecaaf79283b752e13e7/fonttools-4.65.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e2c21772fcf70325189707b19f346812690bb1b0bd7e207e6ac205244806b303", size = 2584521, upload-time = "2026-09-10T15:34:09.648Z" }, + { url = "https://files.pythonhosted.org/packages/51/c9/48b07e6c5cf44fa56f758a04c3772a66c0e9ba82bbe22077e4076746a62b/fonttools-4.65.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:64c9b26816415b5e3d899e9077109d327b22140fe3c4066644d8cdbad5bb1569", size = 5395399, upload-time = "2026-09-10T15:34:12.38Z" }, + { url = "https://files.pythonhosted.org/packages/fa/2d/5cc5a10c8ed56079d6c2e9e3e5920622529a2ae045c9f47a6055ccb1a319/fonttools-4.65.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6dd6243f60e2d6160c2966e1e14020dc261ffd741b69a2e4ca8bfd051592e4b7", size = 5376659, upload-time = "2026-09-10T15:34:15.239Z" }, + { url = "https://files.pythonhosted.org/packages/ab/6f/ccf33739d936bb3afa1655a225be7ee5d63d6d3c8b7d0e570bc5a2a7b899/fonttools-4.65.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:834962fd7cf21c58e81ac50a59e6ed2306f9df5e3dd481dad1cd7d2c4c60b773", size = 5336795, upload-time = "2026-09-10T15:34:17.817Z" }, + { url = "https://files.pythonhosted.org/packages/7e/c1/ffd17483f2094f0f4118974295b514b5b82afd4f6e3c80c23f01684e97a6/fonttools-4.65.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:580eb68ff7bd6954a7a76afddd864bfc66eaaf5f5c20dd6ead9186d0055a4ffe", size = 5496530, upload-time = "2026-09-10T15:34:20.241Z" }, + { url = "https://files.pythonhosted.org/packages/b1/19/9aca7712d0676ba5f8d1530ce20478a9bb09cccd0153d56693337379cdcf/fonttools-4.65.0-cp313-cp313-win32.whl", hash = "sha256:7a18b2ffd44249fe84289253197aa65ad4f2de554c0d381f18b1f5939bc6bc60", size = 2430392, upload-time = "2026-09-10T15:34:22.906Z" }, + { url = "https://files.pythonhosted.org/packages/1f/6f/f015dea0f4354e0798751b657cea2dee482914737f88bf1a078349ce92cf/fonttools-4.65.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ae1846b0f192fd485d26a455af19b8f5cf05aff08f9836f533913d8fcea133c", size = 2481620, upload-time = "2026-09-10T15:34:25.816Z" }, + { url = "https://files.pythonhosted.org/packages/e6/35/f894ceb867118c0261d0f69a9bd516b045a3754238f76c88a49513ac7a83/fonttools-4.65.0-py3-none-any.whl", hash = "sha256:3060b8c1fc2329fa20265b7c138614143ea7c1624e26c5c180c76aeb74deae6f", size = 1196441, upload-time = "2026-09-10T15:35:52.347Z" }, +] + +[[package]] +name = "identify" +version = "2.6.19" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/63/51723b5f116cc04b061cb6f5a561790abf249d25931d515cd375e063e0f4/identify-2.6.19.tar.gz", hash = "sha256:6be5020c38fcb07da56c53733538a3081ea5aa70d36a156f83044bfbf9173842", size = 99567, upload-time = "2026-04-17T18:39:50.265Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl", hash = "sha256:20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a", size = 99397, upload-time = "2026-04-17T18:39:49.221Z" }, +] + +[[package]] +name = "idna" +version = "3.19" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/f7/abb373e5757eaec4b922b92f97ec8d6d7e057cf06778247604fbc4e7c3f3/idna-3.19.tar.gz", hash = "sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15", size = 215237, upload-time = "2026-08-18T05:14:24.27Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/b0/0e52c878c53f245edd3a11020f20979b3f490f245af532c7cae3027754b5/idna-3.19-py3-none-any.whl", hash = "sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4", size = 68550, upload-time = "2026-08-18T05:14:22.343Z" }, +] + +[[package]] +name = "imagesize" +version = "2.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fb/5e/513ff06670c84e7b9887c1fdf61b2d42b4f574a831f2f1d2222023049d8a/imagesize-2.0.1.tar.gz", hash = "sha256:b2ba6a4dea487a7ebcd53248d3476aca449d30db12a2dde5e0c5ca9624fd77e5", size = 1883774, upload-time = "2026-08-24T12:35:19.13Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/01/f9/575c8d760eae1fc99651b7cc5efd96ad5379ca4d6b53750b0fb4fe983f34/imagesize-2.0.1-py3-none-any.whl", hash = "sha256:ea0c9a0384df69ed86a943a15cde37d0360b82491b3910dc2215e202e62b5b02", size = 14794, upload-time = "2026-08-24T12:35:12.548Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "ipykernel" +version = "7.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "appnope", marker = "sys_platform == 'darwin'" }, + { name = "comm" }, + { name = "debugpy" }, + { name = "ipython" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "matplotlib-inline" }, + { name = "nest-asyncio2" }, + { name = "packaging" }, + { name = "psutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/c4/e4a38f579de4225a561305666f7541cdabb30075def2aa1ac17bd73c1fb5/ipykernel-7.3.0.tar.gz", hash = "sha256:9acaaaf97d16355166e4085afe9d225bfbdf2b7ef520f9df3be8f2b248275e09", size = 184899, upload-time = "2026-06-10T08:41:25.481Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/02/77b271f5dc58bfbc0b577c877b2365d1ffea2afe66a80c13f2312820348c/ipykernel-7.3.0-py3-none-any.whl", hash = "sha256:897eb64da762549ef610698fca5e9675195ec6ac8ec7f19d81ce1ca20c876057", size = 120583, upload-time = "2026-06-10T08:41:23.648Z" }, +] + +[[package]] +name = "ipython" +version = "9.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "ipython-pygments-lexers" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "psutil", marker = "sys_platform != 'cygwin' and sys_platform != 'emscripten'" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, + { name = "typing-extensions", marker = "python_full_version < '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/32/99451b1283ec5d92ad77073f12e1c667dc10775384d8f15c2914207149dd/ipython-9.17.1.tar.gz", hash = "sha256:8919be8c27f20a6f4423145028063f6637b42a03ce57665bb12015ee1f073529", size = 4539289, upload-time = "2026-09-01T08:29:32.6Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/1e/65b59cf518c106aa755e7f7da3099027738687a862ec785060702a481320/ipython-9.17.1-py3-none-any.whl", hash = "sha256:6d1645743cfd1a07eb695d85aa2b5fa66721f8cbae9431d4049f7084bbf06509", size = 639038, upload-time = "2026-09-01T08:29:30.673Z" }, +] + +[[package]] +name = "ipython-pygments-lexers" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" }, +] + +[[package]] +name = "jedi" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "parso" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/46/b7/a3635f6a2d7cf5b5dd98064fc1d5fbbafcb25477bcea204a3a92145d158b/jedi-0.20.0.tar.gz", hash = "sha256:c3f4ccbd276696f4b19c54618d4fb18f9fc24b0aef02acf704b23f487daa1011", size = 3119416, upload-time = "2026-05-01T23:38:47.814Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/93/242e2eab5fe682ffcb8b0084bde703a41d51e17ee0f3a31ff0d9d813620a/jedi-0.20.0-py2.py3-none-any.whl", hash = "sha256:7bdd9c2634f56713299976f4cbd59cb3fa92165cc5e05ea811fb253480728b67", size = 4884812, upload-time = "2026-05-01T23:38:43.919Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "jmespath" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d3/59/322338183ecda247fb5d1763a6cbe46eff7222eaeebafd9fa65d4bf5cb11/jmespath-1.1.0.tar.gz", hash = "sha256:472c87d80f36026ae83c6ddd0f1d05d4e510134ed462851fd5f754c8c3cbb88d", size = 27377, upload-time = "2026-01-22T16:35:26.279Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl", hash = "sha256:a5663118de4908c91729bea0acadca56526eb2698e83de10cd116ae0f4e97c64", size = 20419, upload-time = "2026-01-22T16:35:24.919Z" }, +] + +[[package]] +name = "jsonschema" +version = "4.26.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" }, +] + +[[package]] +name = "jsonschema-specifications" +version = "2025.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, +] + +[[package]] +name = "jupyter-client" +version = "8.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-core" }, + { name = "python-dateutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c5/2a/906772148a06e48885039e0250c340b770a55bbf37b08d6ee0449df369c3/jupyter_client-8.10.0.tar.gz", hash = "sha256:9f7116294dca55f1785be880057d44544db9b1567718d92cb33c58886afb9497", size = 360653, upload-time = "2026-08-28T12:17:10.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/88/7c548de1f6c2ade7c931a3282da73f9274fa6a1531091be682f89c85efb9/jupyter_client-8.10.0-py3-none-any.whl", hash = "sha256:5f73f24f22fa25192cfff6b23c051932a2473a797b05734aff495b392103e14e", size = 110184, upload-time = "2026-08-28T12:17:09.028Z" }, +] + +[[package]] +name = "jupyter-core" +version = "5.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "platformdirs" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/02/49/9d1284d0dc65e2c757b74c6687b6d319b02f822ad039e5c512df9194d9dd/jupyter_core-5.9.1.tar.gz", hash = "sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508", size = 89814, upload-time = "2025-10-16T19:19:18.444Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl", hash = "sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407", size = 29032, upload-time = "2025-10-16T19:19:16.783Z" }, +] + +[[package]] +name = "jupyterlab-pygments" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900, upload-time = "2023-11-23T09:26:37.44Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884, upload-time = "2023-11-23T09:26:34.325Z" }, +] + +[[package]] +name = "kiwisolver" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/07/bd78e6a8fae171ea041ef5bba3ed21a003522fa088834b069b1909981f30/kiwisolver-1.5.1.tar.gz", hash = "sha256:f1303ef2eec81262a4b708c3e858afe58d7c75ad91c1c05266eda7673369859a", size = 104395, upload-time = "2026-08-28T10:28:27.153Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/7b/2de6908edc668427c149af5f93112e931f87e1fa4cab80bac32c5844dccc/kiwisolver-1.5.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b3d78f7bb2b9d9a30345be1474b9aaa8685430b54afb51ba3639b5c6c11e9ed6", size = 123364, upload-time = "2026-08-28T10:25:04.359Z" }, + { url = "https://files.pythonhosted.org/packages/8a/24/e70914415c77c97be7e22c80a0740869cb7428768cc380fdcdf6703e7084/kiwisolver-1.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5025e36fb4fb275cef0a4e30dbb11cb4ae61d1c83deb90189cb5d7e4cafd6b55", size = 66558, upload-time = "2026-08-28T10:25:05.506Z" }, + { url = "https://files.pythonhosted.org/packages/e8/2b/8b08b11833db4d475b8ef1f36174f8d8a7abd31bedd7e794be78e8814b48/kiwisolver-1.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc1a26b8e53395a01c2c611e58602fa47461f136fba7cd5542e6db6d64be1839", size = 64071, upload-time = "2026-08-28T10:25:06.7Z" }, + { url = "https://files.pythonhosted.org/packages/89/00/05c2d0369ac322d22d5c05f84b5c4a6856fa6207fbae42869108a28f0383/kiwisolver-1.5.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:95a02752aa032eef4aed01cda6d9b687c669bd0396bf4519eef8bba22a286720", size = 1438206, upload-time = "2026-08-28T10:25:08.254Z" }, + { url = "https://files.pythonhosted.org/packages/c0/05/c941a139f27438c1910d630fdc3ccfdab7c8407c72052299ead12ece086e/kiwisolver-1.5.1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:719a35fa1156db3640555f95ebb94f60a444e64d1c69626b0edef5df78eba225", size = 1248975, upload-time = "2026-08-28T10:25:10.053Z" }, + { url = "https://files.pythonhosted.org/packages/58/a1/2669ee5512e39b9d4de25faacaedf788c957f93730c5f7c63993ec4f5933/kiwisolver-1.5.1-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:febcce10f2bcdbb80b4ea919238a6a4ac13dbc4c7cadbe8d5d75c3682f8b5404", size = 1266301, upload-time = "2026-08-28T10:25:11.754Z" }, + { url = "https://files.pythonhosted.org/packages/28/b8/353f52f2c7f861a9e90cd2e8f90f85b3ad03060835f823e08298d094c463/kiwisolver-1.5.1-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1d852545c4d0e35a72728d072cbaa59e2fa7dd84bdf01e068d670dd0ceb58eb6", size = 1319708, upload-time = "2026-08-28T10:25:13.559Z" }, + { url = "https://files.pythonhosted.org/packages/21/0e/14b83200eadc2c1d63b76bac01c1813bf072aecf567429f303e00b70258e/kiwisolver-1.5.1-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:2e10ae1bba1899188b33557c10d73affcc12033edd18adddb57d209039976a4c", size = 971720, upload-time = "2026-08-28T10:25:14.934Z" }, + { url = "https://files.pythonhosted.org/packages/86/91/9d43d84d23b1cbff72a142d387ead1ea03db0cba8ff86ed5335addad3cc9/kiwisolver-1.5.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b69602970994a2ed8bbfa78c2f0394a7435226c6040489702d9f0a0ad0c07052", size = 2200119, upload-time = "2026-08-28T10:25:16.636Z" }, + { url = "https://files.pythonhosted.org/packages/ff/7c/f2bd9616f27ffb5e17cecc0baa5d0bbcee7e55aeddc0ccc871d69e2fc3ee/kiwisolver-1.5.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d50de98e8d807dc31822fff96f50293163a62418eb65487a21b42713d72ed0b7", size = 2295005, upload-time = "2026-08-28T10:25:18.374Z" }, + { url = "https://files.pythonhosted.org/packages/ba/17/ee671b72bf8f46a08379d4392c65582541759a542428197562f2898294ad/kiwisolver-1.5.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:3221f78211074f561c44ca42eac0619828171bec15a2c4cf6f7747d07df76e8e", size = 1960982, upload-time = "2026-08-28T10:25:19.893Z" }, + { url = "https://files.pythonhosted.org/packages/2e/f7/0e26b4c05bee3bdb0f048dfa305e4fe701999ea17b51e9c616ef91035bbe/kiwisolver-1.5.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0ba9527afc80ae3d7814ed98b6572d02bf85eaf48065678342c5f0c6dab7a8c7", size = 2464918, upload-time = "2026-08-28T10:25:21.65Z" }, + { url = "https://files.pythonhosted.org/packages/ae/62/6eb431133d30ce656ac1e5ff72fac70dd34d54c3984f4011b9ac8bf77d54/kiwisolver-1.5.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e12dfea7f5fc2a34a9080efbf79c4c44eb380ec5b9c6fea09407e08f0d1e941d", size = 2270967, upload-time = "2026-08-28T10:25:23.643Z" }, + { url = "https://files.pythonhosted.org/packages/bf/9f/6f9e489c188200e6fb3193935501894811e8c97577c8ffe9033589bf3521/kiwisolver-1.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:1a7587dc335f2c0f5bd577fd0540bd16c66006bdb60f759a1059f025e6c4f071", size = 70744, upload-time = "2026-08-28T10:25:25.061Z" }, + { url = "https://files.pythonhosted.org/packages/c6/6d/dfc430d1d43957061599adea3f08ea982bb6f4ab601a8c974bedcf2ba850/kiwisolver-1.5.1-cp311-cp311-win_arm64.whl", hash = "sha256:e4e4523d6f336708d732516e6cfca7796cf3d96c9474eb5aecf6165f2f1fefc3", size = 68404, upload-time = "2026-08-28T10:25:26.186Z" }, + { url = "https://files.pythonhosted.org/packages/6b/9b/65b302742389c6f96f2956bef5decf26011309feb2fc5d79613af18adea4/kiwisolver-1.5.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:63fb7294b768f444eb4b068965f2662f28c2fd4161e23bd60fcf3ff27b74c046", size = 123876, upload-time = "2026-08-28T10:25:27.44Z" }, + { url = "https://files.pythonhosted.org/packages/71/74/c21f339956f6f691b2ed7e31d5f3ae767304df6c460192739fc830853051/kiwisolver-1.5.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0ebdef3eae5336568147c39a55be6a2036ffde53faa9ca2d978989ae7c2da12c", size = 66487, upload-time = "2026-08-28T10:25:28.728Z" }, + { url = "https://files.pythonhosted.org/packages/84/e5/bdb34e21523e01dceda064d63713f3bdec91388af24fba1eca7ea5e85864/kiwisolver-1.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1798e83840c3f627246104c4d8a9639c60fa068adf9ce92b61791781fa8a68c1", size = 64660, upload-time = "2026-08-28T10:25:30.071Z" }, + { url = "https://files.pythonhosted.org/packages/fc/f4/dadfec469313c7f428efa7e84b4aba9732f813c13ea7131a24b7b008ef57/kiwisolver-1.5.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:34633ecf50d16187ab8e5528b7a2530f2feb4e23f300db4672538b51cfc5cd38", size = 1477929, upload-time = "2026-08-28T10:25:31.495Z" }, + { url = "https://files.pythonhosted.org/packages/6f/35/09c58daac34e6f6ea5c6dee0094b422118e5a7c265586008a95fd135ac5f/kiwisolver-1.5.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d27c2123977cb9269c30a49ba45f03a4323017ef693e19db4ec9dbe1299a3002", size = 1278499, upload-time = "2026-08-28T10:25:33.375Z" }, + { url = "https://files.pythonhosted.org/packages/19/32/739765e24fbad29d13f83e546ea4abc215a78cea9d677ca09025b027724d/kiwisolver-1.5.1-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6a797a1cefc8b9c93170db580337e1fe3d011ad18b1299943231279406342048", size = 1296677, upload-time = "2026-08-28T10:25:35.059Z" }, + { url = "https://files.pythonhosted.org/packages/df/32/03304d1010e2cc45e5b3b52cef7e43fed3a2a5cd6c87a89b4a88e1d85b5d/kiwisolver-1.5.1-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2551cf9917af48ee7c4b29cc82320489508cf96fd26a51f6fc124de661cd44c7", size = 1346037, upload-time = "2026-08-28T10:25:36.705Z" }, + { url = "https://files.pythonhosted.org/packages/3e/57/4c49377bfd274450dd72ecaa13eaac32ea804a03363e4d1db0c5aa999ceb/kiwisolver-1.5.1-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:38f6e0deb4d0a4615efe0c4efc5990b06ae450ab50a0b321c0b078b6d238c083", size = 988248, upload-time = "2026-08-28T10:25:38.299Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c3/38df144a08b6c5d75ca4504e5cc3141bb3bfef64c04f4ef48204f42711b6/kiwisolver-1.5.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bfd1de989b3330420e29de39352f5c049905c9e3ee67233a50d550e3d652c148", size = 2228722, upload-time = "2026-08-28T10:25:40.038Z" }, + { url = "https://files.pythonhosted.org/packages/e7/11/3221838a89cd64d9b386353e000cd8a296069a20fbe3584507fdfd5bebae/kiwisolver-1.5.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1209042a623ddfda5497e4066c7b77651dde8e1d3a9dd97599dc7e97f3b9b78c", size = 2325216, upload-time = "2026-08-28T10:25:41.699Z" }, + { url = "https://files.pythonhosted.org/packages/83/d4/075c219230697bb5db910d37262b9bacf880f92b4811a02ab81ed073a253/kiwisolver-1.5.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:26e8268480be5061d509e29669d59103c067a26377a56491630ece11762e3858", size = 1977689, upload-time = "2026-08-28T10:25:43.559Z" }, + { url = "https://files.pythonhosted.org/packages/bb/08/1d219c3c2dd960983d0d4da623d916e9de6385df2b0bab3d1af0e9b8fccc/kiwisolver-1.5.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:d79308fa689fac89cbcfbd4dbfc80b5f95c54c5a7fd4d194be221f9d33d026e6", size = 2491443, upload-time = "2026-08-28T10:25:45.242Z" }, + { url = "https://files.pythonhosted.org/packages/ba/d3/024208ec1079d273f1047468d1bdffbf38bb75b7b268090fd3a0301b9d9a/kiwisolver-1.5.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b03af77d77e50edba2030fd5f7c352ff209314b09030a3cba7c14edf9a09a444", size = 2295200, upload-time = "2026-08-28T10:25:46.984Z" }, + { url = "https://files.pythonhosted.org/packages/6e/7c/7b210498f9f92e1cd7855f260fa69ef056881087b199ee20c208f0e4189a/kiwisolver-1.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:06a6917674de9e0fe3f66f5430787f59a9f2ddb64af9b714eaec547e29ef5c19", size = 70748, upload-time = "2026-08-28T10:25:48.444Z" }, + { url = "https://files.pythonhosted.org/packages/94/61/ef0daa157c8bb23672f7423e0d14c39db1dc6ef8ed47e6bc54c9c1bef3bf/kiwisolver-1.5.1-cp312-cp312-win_arm64.whl", hash = "sha256:ad8b9671348d7c8716715652ae11f85ed0eb99e265a2df2ca490577d69860b2c", size = 68324, upload-time = "2026-08-28T10:25:49.81Z" }, + { url = "https://files.pythonhosted.org/packages/08/c1/88018321d976f53c421e379c43bc6993e70ce0c8a3ec5edc4bfe102257f6/kiwisolver-1.5.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:b6ae6a0328f0bc035741820fdeecdcd67bf4694eee03972e843663107122f450", size = 62272, upload-time = "2026-08-28T10:25:51.02Z" }, + { url = "https://files.pythonhosted.org/packages/85/d2/712bc17ea4f1d216034928069d612defbc6c95a471c55a7203a39faecb1a/kiwisolver-1.5.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:886fc26012f0e8b5f69d1cfe6d711f6b11f194621539bf8e6bb1c25c5dc82724", size = 64481, upload-time = "2026-08-28T10:25:52.22Z" }, + { url = "https://files.pythonhosted.org/packages/1b/e6/6c5380d676f43b6d918033962ea5e72360ca69e5a404154bc496b598ffdb/kiwisolver-1.5.1-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:aefe930d113798330e9462f7874542977869c0613cba3262e2de3a8d5dee8f3a", size = 66260, upload-time = "2026-08-28T10:25:53.387Z" }, + { url = "https://files.pythonhosted.org/packages/92/6a/7087f5822cc8bb272679641404b1966a42504dac9ee74e2b33840475a0aa/kiwisolver-1.5.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a5ca5aebae78a0bc13c1943af4af615d4966c5b650b05d5aa83b50e427196fee", size = 123876, upload-time = "2026-08-28T10:25:54.644Z" }, + { url = "https://files.pythonhosted.org/packages/5c/4b/9f385087ca09ee5ab9c09c6832561a7d2f7c78d3e5661d511e669f70e439/kiwisolver-1.5.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1ed0f5e49d0ceff8b72190824d9e59c062fbbc02c231b853112c78474b3f5ec2", size = 66487, upload-time = "2026-08-28T10:25:55.899Z" }, + { url = "https://files.pythonhosted.org/packages/47/8b/40d33ffd2f378094ed462e9a9a0907e59d4de9845e65a59561272da350d4/kiwisolver-1.5.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:77a4c8187a5948d7f8795adb765a3c7b553d07d86d88e43038fc32fc1fb9a3f3", size = 64673, upload-time = "2026-08-28T10:25:57.048Z" }, + { url = "https://files.pythonhosted.org/packages/ab/43/86aacc027959108b4c66eeae8b73cedb057dfa6eb3a335d05ad65197081c/kiwisolver-1.5.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:74ad5c3dad54a4641b4c28cd15ded70899d04459c6c7aeacafea716be97cce6d", size = 1477992, upload-time = "2026-08-28T10:25:58.479Z" }, + { url = "https://files.pythonhosted.org/packages/ed/40/b1d0369048c79733a32c8abb0f2718532e6630641368e33a81384246e844/kiwisolver-1.5.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21e46b23a2da695c364124817bc01d970effd5483147f8d66a6a7167e3f6b851", size = 1278821, upload-time = "2026-08-28T10:26:00.121Z" }, + { url = "https://files.pythonhosted.org/packages/61/a1/fa71c1792272ff9461432715ae60ffb7e11a4d7ac3bf68961b9cab6c60cf/kiwisolver-1.5.1-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:75d9b1cf8258462dbdc1eeda718c96ea7f079324c09067f6daabfcf37712b7fe", size = 1296805, upload-time = "2026-08-28T10:26:01.868Z" }, + { url = "https://files.pythonhosted.org/packages/a3/49/3f0bd94af8e06ecc47eb834b195a06f05d48711ceb2352c56d6835160f0e/kiwisolver-1.5.1-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8fca690b00c4c48f6c2a547b0160ed511357093a4e4c9b47e0fadf3128066d89", size = 1346109, upload-time = "2026-08-28T10:26:03.59Z" }, + { url = "https://files.pythonhosted.org/packages/a4/44/3afe6ef9cf06d61220953a8963e94eca978491be1d9547cb01d82a1efa08/kiwisolver-1.5.1-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:876bbfd276473d3daffe30e8c975df4ed9429967b41a6cb362dbb5155b6f13ad", size = 988252, upload-time = "2026-08-28T10:26:05.306Z" }, + { url = "https://files.pythonhosted.org/packages/e4/30/a12bd7a7285a211e1747c3eec77b8c614dbfcc1dad942f7611a1a6921ae5/kiwisolver-1.5.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f942903fde7363d1d879057ec5de01310efda2597161784d752fa9953a01a71a", size = 2228846, upload-time = "2026-08-28T10:26:07.312Z" }, + { url = "https://files.pythonhosted.org/packages/a1/6b/233e2958abf0dab7b18d07e52f286e02e519d7651bfbbe97af9347564109/kiwisolver-1.5.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c90d3022d8a94778939cda8638c6c8da8fa757b8958dad7ec868ce29c87681b8", size = 2325583, upload-time = "2026-08-28T10:26:09.093Z" }, + { url = "https://files.pythonhosted.org/packages/42/8e/7673060a27b01405b580058510adef34687069d229800239f5e44682d4d0/kiwisolver-1.5.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:8a34616dc2521cc8dc1d7d081734da63539f021ac0450ce950908340c6e7aa2f", size = 1978221, upload-time = "2026-08-28T10:26:11.127Z" }, + { url = "https://files.pythonhosted.org/packages/3f/7b/1b882fc1a8b4a0bb8084e7d1d85004116d08c92c0705d31f2928dec607f2/kiwisolver-1.5.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:8bf4df63592c2a66b4f8edc5df2544998c288aa02f96ce0acd880cd1de8c8127", size = 2491819, upload-time = "2026-08-28T10:26:13.348Z" }, + { url = "https://files.pythonhosted.org/packages/39/9c/426deb49e62c5f69464b64bbeca064d3b758a7506b8913d986ef34f4619c/kiwisolver-1.5.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d09037ca068d784ebc4aec290ef952ca27ac15dd9c0b5801a88c6e1096b83e6b", size = 2295520, upload-time = "2026-08-28T10:26:15.042Z" }, + { url = "https://files.pythonhosted.org/packages/f5/22/deabbb3ad6d918d74b7831b2d8ae7151b09d21c87974e5ee8a456f58c94c/kiwisolver-1.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:dc23390afe9f4ef9ac3bcc72a03a56eebbde03f4c571a32cb38f859cff9a6524", size = 70758, upload-time = "2026-08-28T10:26:16.504Z" }, + { url = "https://files.pythonhosted.org/packages/b9/71/02fa5c2fd92068bb8952847e70ee6c5cb280e7febe11653d17812acc53dd/kiwisolver-1.5.1-cp313-cp313-win_arm64.whl", hash = "sha256:186884a58486651e3c217b6acea0a53eaa9498fdd472057c46f2f0fb5c25aad5", size = 68329, upload-time = "2026-08-28T10:26:17.658Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c4/1407df7512a5b36cc79840e01710dc575733c461b13ab866cae77eaf87f3/kiwisolver-1.5.1-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:482676e5bd48d70ac99d9fc78863469845421e01184fa83f1f9366dc49f7e974", size = 134002, upload-time = "2026-08-28T10:28:08.881Z" }, + { url = "https://files.pythonhosted.org/packages/16/45/c37a21ad5c0ab581a93c55ad544721aaa1f0ae94edb29c6a678a23d013e6/kiwisolver-1.5.1-graalpy312-graalpy250_312_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:072bdb15a3c19a5b5dbc8f8fb1f4e1884bf4f3507eeb4cc6334401274d37a5c0", size = 194292, upload-time = "2026-08-28T10:28:11.06Z" }, + { url = "https://files.pythonhosted.org/packages/a6/c1/69f00d627949580e43d57af0aa465df46868d7c29801c137a55374101294/kiwisolver-1.5.1-graalpy312-graalpy250_312_native-win_amd64.whl", hash = "sha256:a5a00665d1a0e26763a7338d7e911d4598fbc1d50dd0d6b7919b7dc6c5d6569f", size = 73362, upload-time = "2026-08-28T10:28:12.449Z" }, + { url = "https://files.pythonhosted.org/packages/b5/1d/59ba570b1774e95e97fde3a0981b2e22118a7a495f73bf74cedc538566a0/kiwisolver-1.5.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:416ba7ff9f233b7036689bb5a3783537e838ad483f63558d2a800f75afe738b1", size = 59450, upload-time = "2026-08-28T10:28:20.383Z" }, + { url = "https://files.pythonhosted.org/packages/22/98/a6849f04dc18b5400e8b98affa2cd8fd86ed583085f036e57b32e571f4fa/kiwisolver-1.5.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:8af9b142ad719ae3a911ebf616bc4b78b32bbab84d6a40d3ad2f129670509957", size = 57400, upload-time = "2026-08-28T10:28:21.632Z" }, + { url = "https://files.pythonhosted.org/packages/f4/ce/a7dc71353dd06a4cbe02222773f52d4a28c81e5a452a75797f8ed113dc99/kiwisolver-1.5.1-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5daa1f19e097050b9c4d9a78fcc9263cb96c9dfae08037ddc1b7c4ad1889f2a2", size = 79891, upload-time = "2026-08-28T10:28:22.936Z" }, + { url = "https://files.pythonhosted.org/packages/10/b1/d61c61a84ff85d1a36a99df2c152b59ffedb1d356c598902aba44abcdb60/kiwisolver-1.5.1-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cdaeeb6c350106df6bf9d873395973e5f066a9713200b72cd64f55d0a3eafab6", size = 77605, upload-time = "2026-08-28T10:28:24.322Z" }, + { url = "https://files.pythonhosted.org/packages/d3/52/5aef56f21a460a6e43ab3cdfc7697d59d7b87deb0ec97a0f7b91aa4a521b/kiwisolver-1.5.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:17851e5dad4484be0cbccbde3b15331deae036de9aebd45eed964487802b172f", size = 98465, upload-time = "2026-08-28T10:28:25.696Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, + { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, + { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" }, + { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" }, + { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" }, + { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" }, + { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, + { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, +] + +[[package]] +name = "matplotlib" +version = "3.11.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "contourpy", version = "1.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "contourpy", version = "1.4.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "cycler" }, + { name = "fonttools" }, + { name = "kiwisolver" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "numpy", version = "2.5.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "packaging" }, + { name = "pillow" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e7/c8/9aa712a0afb882649424dd8de8ad9aa6235e796e84c6052e8f6dc1598d0d/matplotlib-3.11.2.tar.gz", hash = "sha256:cec596316640f2b394b8f0daa0ea61a8eae82d017b620b9f202befb972a59ea4", size = 32660610, upload-time = "2026-09-11T19:05:31.214Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/a9/a7fc5a63c427aeb9a4b99d6a0449f891be0952d3aee2b85229099f7b9f54/matplotlib-3.11.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5e1e923a3fc3326b99ec0a6ff1ab1338ac6c6cc62ad9d8a9c944197c7f8c6221", size = 9461046, upload-time = "2026-09-11T19:02:59.277Z" }, + { url = "https://files.pythonhosted.org/packages/0b/d7/59d8ee63e4dee845d953515c50d67e6b8cefa953b453c6b803f197ae556e/matplotlib-3.11.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c27e577ece613ea12a0790e00b4eb80d901c59a3e16cad474f31d8b1529690b9", size = 9290872, upload-time = "2026-09-11T19:03:02.295Z" }, + { url = "https://files.pythonhosted.org/packages/2e/a4/1ca765c63a60e3096ae2ad132eb25f6f7eab0377418cd0472808befd9665/matplotlib-3.11.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:07d9b9fa60cd4c393692f50d0bb03123242ddf61c99bb0e95e75feb354e7c1a8", size = 9854405, upload-time = "2026-09-11T19:03:04.796Z" }, + { url = "https://files.pythonhosted.org/packages/d7/3d/f28ca971a4ad0ed83ebdd60230b09d99de8b91aba47964fac3a81eb2e2ba/matplotlib-3.11.2-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:30ec15d7eefee71de16b7c689b42ba49715a4644650b76a6c7c70d79daf24e91", size = 10660507, upload-time = "2026-09-11T19:03:07.402Z" }, + { url = "https://files.pythonhosted.org/packages/f7/0c/a743556bc64a9b57d2246b14d91b713078adfd2df4199f542df1861737a9/matplotlib-3.11.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:116cdb0eb0eb5644fc98eb2975d4b4dd4ad35e5c8e6b851c22e6976f371f7ab5", size = 10801141, upload-time = "2026-09-11T19:03:11.357Z" }, + { url = "https://files.pythonhosted.org/packages/66/54/91fe3fdfa29100b4668cbf9721577a10acde6e009694618230e4e7a97527/matplotlib-3.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:a24d5fd36e4f0e742c3851dcd20810e56a95633a342e4bf6cb591c678e8fe61f", size = 9329982, upload-time = "2026-09-11T19:03:14.25Z" }, + { url = "https://files.pythonhosted.org/packages/49/c1/13b70871c98d7e93f0d2ed71f226b8d6f873f1372124046068a6b4902fb5/matplotlib-3.11.2-cp311-cp311-win_arm64.whl", hash = "sha256:57b9ea60a835937c2012861923cbb91f47db8565775d326d1c42fc926aa10351", size = 9023542, upload-time = "2026-09-11T19:03:16.878Z" }, + { url = "https://files.pythonhosted.org/packages/cb/ce/1bfcc4873b121597791ad74032943b123218c0613af0b97e8dd05e916fb1/matplotlib-3.11.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ef752769cd962f39ea0b6ffc82d1ea43a0012c5a6157c7a075212fa509cfcff2", size = 9476466, upload-time = "2026-09-11T19:03:19.45Z" }, + { url = "https://files.pythonhosted.org/packages/a6/c4/7f5f3601ee69baf072c0c7d3ce60c03e0618621c5a56c34a62a460e29d11/matplotlib-3.11.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ef31985c4dedb5f1424e1aec6849a47dd37689cb7fa3c20b1b82187f26806261", size = 9305583, upload-time = "2026-09-11T19:03:22.39Z" }, + { url = "https://files.pythonhosted.org/packages/b8/90/2b3fd67ee273163faeda6d514be70b5596eaa0fd77b60ffc294ad0b34f5f/matplotlib-3.11.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:df4f7784aca81a94f254c0a2767d592ee25f407e488f5fa7203e51093fb6ca27", size = 9860353, upload-time = "2026-09-11T19:03:25.049Z" }, + { url = "https://files.pythonhosted.org/packages/f4/84/32549e7a462dc311aed2ab62e5d2538028840b5c53a8be0195c789937c3d/matplotlib-3.11.2-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b9a7ad579856284135e401ecc918c5f8a017ee30539298862a109f51b971710", size = 10670348, upload-time = "2026-09-11T19:03:28.108Z" }, + { url = "https://files.pythonhosted.org/packages/84/39/02e21b74f7439bd643d717ea846006d46e309e6d29b632b57751265311d6/matplotlib-3.11.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3aa4b8516fd26659e4363abbf317c703d9116496c5db2e9d0609a2866dd39dd2", size = 10810580, upload-time = "2026-09-11T19:03:31.402Z" }, + { url = "https://files.pythonhosted.org/packages/04/93/0d239bde12b308262265c2d98909b2f0ecad2b5deeae96241642e822e9c7/matplotlib-3.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:c5c1c68ee401fc98271263410f0e5ce88285abacf7627132914e8adf3d70ff43", size = 9349409, upload-time = "2026-09-11T19:03:34.195Z" }, + { url = "https://files.pythonhosted.org/packages/49/a8/06baf901c02246c8a222b655cc4540ef9c15e1549a04e07927f9cde716c3/matplotlib-3.11.2-cp312-cp312-win_arm64.whl", hash = "sha256:643ff850d8e0f5b8319337f87ed3cb59506afb3df3cc48de777d85871233be7b", size = 9028084, upload-time = "2026-09-11T19:03:37.032Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ce/fc58855a3d17f6cb8a87b6f9ccd100f65432a3a7ffed57309cbf14c78987/matplotlib-3.11.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7d43ff8cebb50840648cb6429b2228621dbd709010f3117b3740abb20abf21c0", size = 9476987, upload-time = "2026-09-11T19:03:40.17Z" }, + { url = "https://files.pythonhosted.org/packages/a9/29/2a47b700545aca050e0ed73c89ba21e08407e11f5f42a567421b220de6c1/matplotlib-3.11.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2a8285cea8ef4d92aa041d1c33788bcae82248503300f93f1ca2136b9049452f", size = 9306050, upload-time = "2026-09-11T19:03:43.103Z" }, + { url = "https://files.pythonhosted.org/packages/a9/df/e7c10292f348cf55178a5b3c0092a38ea68891a3945f199ae8b7b8ac9dc1/matplotlib-3.11.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1944895967f87c84c9b4bad29a707b31f5b36df4a3a2339ea1f8ea3ce5105539", size = 9861060, upload-time = "2026-09-11T19:03:46.044Z" }, + { url = "https://files.pythonhosted.org/packages/e4/b9/b978de6d43d47f1d4d8e653fac32c16d8d2e5f46bbbb822e26d7cb1adece/matplotlib-3.11.2-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:af2661f6ac6bbd1d081996f54fdd9385715c625ace8cec0869055c0cfbf38981", size = 10670885, upload-time = "2026-09-11T19:03:48.942Z" }, + { url = "https://files.pythonhosted.org/packages/a3/80/d72f61bb2631ac15d17fada1f17e0f99fecba69d8376d34f17cf93b7eddd/matplotlib-3.11.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7e5a90f8a707ebb6004a713b1cff091a40cc5df4c7c1cb165e5a505ebc11c292", size = 10811222, upload-time = "2026-09-11T19:03:51.665Z" }, + { url = "https://files.pythonhosted.org/packages/94/2e/6d1d33f242c705b5c6c6fb3f0fc141add51cb1abb62912e59de0835d28c4/matplotlib-3.11.2-cp313-cp313-win_amd64.whl", hash = "sha256:bc067c462a86f0e57bf52fc6e058d90171a5420007dac00c46e90153050c69a7", size = 9349539, upload-time = "2026-09-11T19:03:54.534Z" }, + { url = "https://files.pythonhosted.org/packages/bb/bb/c0aa86a7f4c0e62f1c3c0711e361f6f23f87eb9018732a5e11994bd1b7ec/matplotlib-3.11.2-cp313-cp313-win_arm64.whl", hash = "sha256:3e8576f7c47e02fd4f21f44171302d2d1d58d4471d46da3d71fe8899d19539d9", size = 9028295, upload-time = "2026-09-11T19:03:57.261Z" }, + { url = "https://files.pythonhosted.org/packages/0f/d9/a1218a31fa2d8082eb893548990ad09a2005ebda1b2b89dad88a8308e51a/matplotlib-3.11.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:854df8d7dfe9fdffcbaa6f39e44a6c24b409cb4d7561fbc09213b157d833f6a6", size = 9457702, upload-time = "2026-09-11T19:05:22.086Z" }, + { url = "https://files.pythonhosted.org/packages/68/d7/a9fde05d87c3c853f233ec20c5b5c3a1c86035e1ed4bfa397cd54d46ec90/matplotlib-3.11.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:eac4b07d4e3743b172451e122ea964f72f152879d4f9adcf3f3d33e518f12ead", size = 9287753, upload-time = "2026-09-11T19:05:24.677Z" }, + { url = "https://files.pythonhosted.org/packages/ec/79/ea2ae4eab84f011c1dc8145864f78e5a63adda8efb95557ef36cc38e6da2/matplotlib-3.11.2-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7ef7a53b66780e5d942923724f08577fbc5be1f7322da0f0f3f9dcaa45dd803d", size = 9848259, upload-time = "2026-09-11T19:05:27.455Z" }, +] + +[[package]] +name = "matplotlib-inline" +version = "0.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bd/c0/9f7c9a46090390368a4d7bcb76bb87a4a36c421e4c0792cdb53486ffac7a/matplotlib_inline-0.2.2.tar.gz", hash = "sha256:72f3fe8fce36b70d4a5b612f899090cd0401deddc4ea90e1572b9f4bfb058c79", size = 8150, upload-time = "2026-05-08T17:33:33.49Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/09/5b161152e2d90f7b87f781c2e1267494aef9c32498df793f73ad0a0a494a/matplotlib_inline-0.2.2-py3-none-any.whl", hash = "sha256:3c821cf1c209f59fb2d2d64abbf5b23b67bcb2210d663f9918dd851c6da1fcf6", size = 9534, upload-time = "2026-05-08T17:33:32.055Z" }, +] + +[[package]] +name = "mistune" +version = "3.3.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/92/328a294a6de83bacb95bed01f04e0eaff4e3616ee359fc821a5dfc539b02/mistune-3.3.4.tar.gz", hash = "sha256:58b5c96d6fcb61190dfe5fae498d2b2065f99cf61e9649418fd54cf1ada86dfe", size = 121426, upload-time = "2026-07-22T05:22:30.89Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/e4/288365afae98953bc01de09f686f40d8ee84578135aa7767d5d4e60b5278/mistune-3.3.4-py3-none-any.whl", hash = "sha256:ee015381e955e370962968befe1d729ab60fafb6a715ac6751763fbce38c8d4a", size = 66862, upload-time = "2026-07-22T05:22:29.419Z" }, +] + +[[package]] +name = "nb2plots" +version = "0.7.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ipython" }, + { name = "matplotlib" }, + { name = "nbconvert" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "numpy", version = "2.5.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinxtesters" }, + { name = "texext" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/47/1c/56467472e0dd8824f21d55ef2f38f245d1d60667e05995aa28a8a953380d/nb2plots-0.7.2.tar.gz", hash = "sha256:4f0de757fce4d4f6937ebfa2ffbabb7feb87134c61c944055e95a1999aab2d8b", size = 126093, upload-time = "2023-10-05T09:49:56.971Z" } + +[[package]] +name = "nbclient" +version = "0.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "nbformat" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/a5/b3bae4b590c0cbcada2c63a34f7580024e834a8ba213e949a2f906705787/nbclient-0.11.0.tar.gz", hash = "sha256:04a134a5b087f2c5887f228aca155db50169b8cd9334dee6942c8e927e56081a", size = 62535, upload-time = "2026-06-05T07:52:41.746Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/c9/94d73e5a01c5b926c3fa2496e97d7a8dc28ed5a77c0b2ed712f1a62e6694/nbclient-0.11.0-py3-none-any.whl", hash = "sha256:ef7fa0d59d6e1d41103933d8a445a18d5de860ca6b613b87b8574accdb3c2895", size = 25288, upload-time = "2026-06-05T07:52:40.115Z" }, +] + +[[package]] +name = "nbconvert" +version = "7.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "bleach", extra = ["css"] }, + { name = "defusedxml" }, + { name = "jinja2" }, + { name = "jupyter-core" }, + { name = "jupyterlab-pygments" }, + { name = "markupsafe" }, + { name = "mistune" }, + { name = "nbclient" }, + { name = "nbformat" }, + { name = "packaging" }, + { name = "pandocfilters" }, + { name = "pygments" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/01/b1/708e53fe2e429c103c6e6e159106bcf0357ac41aa4c28772bd8402339051/nbconvert-7.17.1.tar.gz", hash = "sha256:34d0d0a7e73ce3cbab6c5aae8f4f468797280b01fd8bd2ca746da8569eddd7d2", size = 865311, upload-time = "2026-04-08T00:44:14.914Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/f8/bb0a9d5f46819c821dc1f004aa2cc29b1d91453297dbf5ff20470f00f193/nbconvert-7.17.1-py3-none-any.whl", hash = "sha256:aa85c087b435e7bf1ffd03319f658e285f2b89eccab33bc1ba7025495ab3e7c8", size = 261927, upload-time = "2026-04-08T00:44:12.845Z" }, +] + +[[package]] +name = "nbformat" +version = "5.11.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fastjsonschema" }, + { name = "jsonschema" }, + { name = "jupyter-core" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/31/72/b3446efab8756e7df4b8ec587f8e611cb5a7249e4323db480802f1d3be04/nbformat-5.11.1.tar.gz", hash = "sha256:32d4521c68c6e7d5b29c76defaeed9f42ea733142b9b19f88277ce10390b9c4d", size = 147775, upload-time = "2026-08-17T08:10:51.942Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/69/ee613f74085ca7103f79cd08d579c4f3177d1d26e5d3d9528d2d6536a707/nbformat-5.11.1-py3-none-any.whl", hash = "sha256:cc6698fa75f4fab8755ead786317815f13a6fee3b53311c0abb1a8b51d52f7ec", size = 79849, upload-time = "2026-08-17T08:10:50.18Z" }, +] + +[[package]] +name = "nest-asyncio2" +version = "1.7.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b4/73/731debf26e27e0a0323d7bda270dc2f634b398e38f040a09da1f4351d0aa/nest_asyncio2-1.7.2.tar.gz", hash = "sha256:1921d70b92cc4612c374928d081552efb59b83d91b2b789d935c665fa01729a8", size = 14743, upload-time = "2026-02-13T00:34:04.386Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/3c/3179b85b0e1c3659f0369940200cd6d0fa900e6cefcc7ea0bc6dd0e29ffb/nest_asyncio2-1.7.2-py3-none-any.whl", hash = "sha256:f5dfa702f3f81f6a03857e9a19e2ba578c0946a4ad417b4c50a24d7ba641fe01", size = 7843, upload-time = "2026-02-13T00:34:02.691Z" }, +] + +[[package]] +name = "networkx" +version = "3.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/51/63fe664f3908c97be9d2e4f1158eb633317598cfa6e1fc14af5383f17512/networkx-3.6.1.tar.gz", hash = "sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509", size = 2517025, upload-time = "2025-12-08T17:02:39.908Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504, upload-time = "2025-12-08T17:02:38.159Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, +] + +[[package]] +name = "numpy" +version = "2.4.6" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.12' and sys_platform == 'win32'", + "python_full_version < '3.12' and sys_platform == 'emscripten'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/49/ec46835a70be8fa6446c495126ac84fdb28cb2558e1620ffb87a10c8b64c/numpy-2.4.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4", size = 16969194, upload-time = "2026-05-18T23:33:13.503Z" }, + { url = "https://files.pythonhosted.org/packages/0e/0d/f5957185c0ee2f3e12f78715aa9e3b353fd83633316c8532b38faa37e3f6/numpy-2.4.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d", size = 14964111, upload-time = "2026-05-18T23:33:17.795Z" }, + { url = "https://files.pythonhosted.org/packages/ad/40/40a40ee0ddf7ceb782c49af278894b686e586d65d8c1889c8b5da01a3d7d/numpy-2.4.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8", size = 5469159, upload-time = "2026-05-18T23:33:20.654Z" }, + { url = "https://files.pythonhosted.org/packages/63/13/f9a8046535cb21deae82f8d03de9617e08882d274fad2539630761888228/numpy-2.4.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538", size = 6798936, upload-time = "2026-05-18T23:33:22.987Z" }, + { url = "https://files.pythonhosted.org/packages/33/a8/6fa8c1a345a8c85dbb21932c447bee07c30a2c2a3f31e369c0a84b300147/numpy-2.4.6-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47", size = 15966692, upload-time = "2026-05-18T23:33:26.62Z" }, + { url = "https://files.pythonhosted.org/packages/02/03/74fe2a4cb3817d94d86402f2506554130a2f01414e299b5a843e5a8a957f/numpy-2.4.6-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93", size = 16918164, upload-time = "2026-05-18T23:33:29.955Z" }, + { url = "https://files.pythonhosted.org/packages/c5/80/3615be3313f7e7696609bc194b9f0101da809df79e859bdb84e0cd043f46/numpy-2.4.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8", size = 17322877, upload-time = "2026-05-18T23:33:34.724Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ac/a691e0fe2675e370d0e08ff905adc49a1c8830e8cae03efe4477e92cd55d/numpy-2.4.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6", size = 18651487, upload-time = "2026-05-18T23:33:38.217Z" }, + { url = "https://files.pythonhosted.org/packages/15/a7/9bc1cd626d7bf6869bfedf27b91b6ab5dd607758bf8e959d6fa80c6a59cb/numpy-2.4.6-cp311-cp311-win32.whl", hash = "sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8", size = 6233945, upload-time = "2026-05-18T23:33:41.331Z" }, + { url = "https://files.pythonhosted.org/packages/c5/31/7fc6239c12bce7e931463251cca4426c465e1876ba3cc785402ef4dd8f4e/numpy-2.4.6-cp311-cp311-win_amd64.whl", hash = "sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147", size = 12608406, upload-time = "2026-05-18T23:33:44.131Z" }, + { url = "https://files.pythonhosted.org/packages/27/83/140f85a466595a16382996a1bf06b2b54bcd597488921b0c9daaeeda72af/numpy-2.4.6-cp311-cp311-win_arm64.whl", hash = "sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577", size = 10479528, upload-time = "2026-05-18T23:33:50.725Z" }, + { url = "https://files.pythonhosted.org/packages/95/2a/3d7b5ac8aac24feaf9ad7ed58f45b0bbc06d37e4338ae84c9f2298b570f9/numpy-2.4.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1", size = 16689119, upload-time = "2026-05-18T23:33:54.065Z" }, + { url = "https://files.pythonhosted.org/packages/ea/12/92c4c131527599e8288d6918e888d88726f84d805d784b771f32408aeaef/numpy-2.4.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb", size = 14699246, upload-time = "2026-05-18T23:33:57.621Z" }, + { url = "https://files.pythonhosted.org/packages/ad/fe/c0a6b7b2ca128a8fb228575147073b660656734b8ebe4d76c8fd748dcc79/numpy-2.4.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41", size = 5204410, upload-time = "2026-05-18T23:34:00.302Z" }, + { url = "https://files.pythonhosted.org/packages/f3/d4/9770d14ba719432bb90a421bfd443872ed0f70f7264b64bec12ea363d5fd/numpy-2.4.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698", size = 6551240, upload-time = "2026-05-18T23:34:02.852Z" }, + { url = "https://files.pythonhosted.org/packages/c9/c6/50a46a6205feba2343f1d6d17438107c5dc491ed1c736e6ea68689fd906b/numpy-2.4.6-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f", size = 15671012, upload-time = "2026-05-18T23:34:05.485Z" }, + { url = "https://files.pythonhosted.org/packages/99/60/14115e6364fa676c5397c2ad3004e527e9aa487abf5d0706ec81bbd08529/numpy-2.4.6-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853", size = 16645538, upload-time = "2026-05-18T23:34:09.265Z" }, + { url = "https://files.pythonhosted.org/packages/ae/c5/693cbe59e57db94d2231fa519ca3978dc9e19da5a8f088588f5c6e947ff2/numpy-2.4.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a", size = 17020706, upload-time = "2026-05-18T23:34:13.053Z" }, + { url = "https://files.pythonhosted.org/packages/ef/fc/85b7c4eff9b4966ade25c2273cf7e7012e92366c032058653934b37de044/numpy-2.4.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2", size = 18368541, upload-time = "2026-05-18T23:34:17.024Z" }, + { url = "https://files.pythonhosted.org/packages/f6/81/e1b27545deedce7f4a0b348618c6b62d74e36a4dc9ccd42f3eb2f85eee32/numpy-2.4.6-cp312-cp312-win32.whl", hash = "sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45", size = 5962825, upload-time = "2026-05-18T23:34:20.3Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ca/feab00bd44aa5fe1ad2c18f08b4d3bb92e26484b0b1d1443897809ed528c/numpy-2.4.6-cp312-cp312-win_amd64.whl", hash = "sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751", size = 12321687, upload-time = "2026-05-18T23:34:23.095Z" }, + { url = "https://files.pythonhosted.org/packages/63/cf/5a6d34850a39d1093558564f77ee8e8e0bee5061151b8f05a55711001ec7/numpy-2.4.6-cp312-cp312-win_arm64.whl", hash = "sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8", size = 10221482, upload-time = "2026-05-18T23:34:25.876Z" }, + { url = "https://files.pythonhosted.org/packages/fb/82/bdab26d7438c6791ca31b7c024ca37c1eab8b726ba236129005cd4a06e45/numpy-2.4.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0", size = 16684648, upload-time = "2026-05-18T23:34:29.41Z" }, + { url = "https://files.pythonhosted.org/packages/1b/30/a80189bcc7f5e4258b3fbc3968d909d1756f54d023299ecc39ad6fdb9ef8/numpy-2.4.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb", size = 14693902, upload-time = "2026-05-18T23:34:33.013Z" }, + { url = "https://files.pythonhosted.org/packages/97/12/70b5d0d7c15e1ebb8a6a84a8caa1d19e181d84fb58bb6d70aca29099dec1/numpy-2.4.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f", size = 5198992, upload-time = "2026-05-18T23:34:36.132Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8c/ebd2a8f8a83541f8d38cc5667e8c2b69cecfd30da6e45693e8158857d44b/numpy-2.4.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3", size = 6546944, upload-time = "2026-05-18T23:34:38.484Z" }, + { url = "https://files.pythonhosted.org/packages/bb/c5/7b863a97a91671a0338f4253bd3b5a3d3852f0692dae91711c9f4a10e787/numpy-2.4.6-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b", size = 15669392, upload-time = "2026-05-18T23:34:41.257Z" }, + { url = "https://files.pythonhosted.org/packages/a5/9d/3584b9984ca4c047aea75214ce1a4c4c73d849bd71b604264b7f5653f8a8/numpy-2.4.6-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089", size = 16633220, upload-time = "2026-05-18T23:34:45.075Z" }, + { url = "https://files.pythonhosted.org/packages/05/ae/7c67fba23bd98caec7c99261f3a16072ade14813486b0282cb29846de832/numpy-2.4.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a", size = 17020800, upload-time = "2026-05-18T23:34:49.065Z" }, + { url = "https://files.pythonhosted.org/packages/d9/5d/3b6725cb31d983c5e66916f5d36f6d7e5521129e4c4404d64f918292a5b6/numpy-2.4.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605", size = 18357600, upload-time = "2026-05-18T23:34:52.709Z" }, + { url = "https://files.pythonhosted.org/packages/f7/da/2ccc6c2fe8898dee01d90c75c5f5f914a23daf99e3e0f59516a08760c8b5/numpy-2.4.6-cp313-cp313-win32.whl", hash = "sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91", size = 5961134, upload-time = "2026-05-18T23:34:55.618Z" }, + { url = "https://files.pythonhosted.org/packages/b5/cd/9cc4dc876fb065d5c220aae4d5e14826b2715331bb7618ce1fb07a679d99/numpy-2.4.6-cp313-cp313-win_amd64.whl", hash = "sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359", size = 12318598, upload-time = "2026-05-18T23:34:58.928Z" }, + { url = "https://files.pythonhosted.org/packages/39/1e/c0bcba1f8694116485fe28fd1be698c278fcda4141c5b0e53a2aed8b12a8/numpy-2.4.6-cp313-cp313-win_arm64.whl", hash = "sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778", size = 10222272, upload-time = "2026-05-18T23:35:02.167Z" }, + { url = "https://files.pythonhosted.org/packages/63/6d/cc5619247c8f4204e507f5883528372e4ac4bb189e579fb859a12e480b1f/numpy-2.4.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1", size = 14821197, upload-time = "2026-05-18T23:35:05.468Z" }, + { url = "https://files.pythonhosted.org/packages/00/58/f1c39161c87d9e9bed660f1ed4bafc0e403d5ec9650b6dd77aead07d489b/numpy-2.4.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe", size = 5326287, upload-time = "2026-05-18T23:35:08.693Z" }, + { url = "https://files.pythonhosted.org/packages/af/57/3917ab0fd97f271a8694513581b8a36c655f111c446852c302f04ccdb6fc/numpy-2.4.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997", size = 6646763, upload-time = "2026-05-18T23:35:11.459Z" }, + { url = "https://files.pythonhosted.org/packages/eb/0f/037e64c494b67581ae18193d770adef354c41f3f2c8ebf865602d949bf8f/numpy-2.4.6-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20", size = 15728070, upload-time = "2026-05-18T23:35:14.79Z" }, + { url = "https://files.pythonhosted.org/packages/21/a6/5d2bae9c9542eb4df16dc9c46dc79c186e9bad53805dfa5399a6023c6db0/numpy-2.4.6-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d", size = 16681752, upload-time = "2026-05-18T23:35:18.836Z" }, + { url = "https://files.pythonhosted.org/packages/92/14/23d1dfb410ae362cd59ce53e936b1513d545eb40db3949ced632e19a459e/numpy-2.4.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67", size = 17086024, upload-time = "2026-05-18T23:35:22.52Z" }, + { url = "https://files.pythonhosted.org/packages/4b/6e/23595a2c642cdf3bc567877064bdd7f91c8b0038a4453cf2daf7248eafe9/numpy-2.4.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd", size = 18403398, upload-time = "2026-05-18T23:35:26.398Z" }, + { url = "https://files.pythonhosted.org/packages/8a/90/0ac3bc947217e66dec77e7cbc6a1979d1af70b6461b82f620d3bccd5e4c8/numpy-2.4.6-cp313-cp313t-win32.whl", hash = "sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab", size = 6084971, upload-time = "2026-05-18T23:35:29.387Z" }, + { url = "https://files.pythonhosted.org/packages/77/71/5673e351671a1d2bd6063b91b44f70c0affea7d1516fa7a6572941ba4aa1/numpy-2.4.6-cp313-cp313t-win_amd64.whl", hash = "sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75", size = 12458532, upload-time = "2026-05-18T23:35:32.175Z" }, + { url = "https://files.pythonhosted.org/packages/3f/88/19d3503c5046e688f049274b27a3ef3d771152fa80d3ba3d01a3dff61abe/numpy-2.4.6-cp313-cp313t-win_arm64.whl", hash = "sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd", size = 10291881, upload-time = "2026-05-18T23:35:35.465Z" }, + { url = "https://files.pythonhosted.org/packages/de/12/b422cc84439adc0d00de605bf4a308890ae5c26f2c71fbd73e5d08fbb0dd/numpy-2.4.6-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662", size = 16847511, upload-time = "2026-05-18T23:36:50.673Z" }, + { url = "https://files.pythonhosted.org/packages/44/53/f481bef68011740f8849418d82db07230e825013f31f4eef5ba5b805316a/numpy-2.4.6-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7", size = 14889064, upload-time = "2026-05-18T23:36:53.879Z" }, + { url = "https://files.pythonhosted.org/packages/7f/57/42ed575c10ced8af951d426bc4e1f8aff16fd851db33f067036215a7f860/numpy-2.4.6-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f", size = 5394157, upload-time = "2026-05-18T23:36:57.194Z" }, + { url = "https://files.pythonhosted.org/packages/6a/ef/f66cc724fcc36c1e364c67f51ae9146090b8b584f27d58b97fdae3edd737/numpy-2.4.6-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c", size = 6708728, upload-time = "2026-05-18T23:36:59.575Z" }, + { url = "https://files.pythonhosted.org/packages/1a/9c/c531f2293b91265d8b48e9b329f54fdd7ffae73cb4134ea10cca4237e9cc/numpy-2.4.6-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0", size = 15798374, upload-time = "2026-05-18T23:37:02.674Z" }, + { url = "https://files.pythonhosted.org/packages/1a/b0/413077f6b1153ed3cba361401c6783bbad6114804a000cc22eb71c13e190/numpy-2.4.6-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02", size = 16747286, upload-time = "2026-05-18T23:37:06.327Z" }, + { url = "https://files.pythonhosted.org/packages/15/ce/e5ec180bc41812edcd8daeb8639d205622c0e8c02259d8ab25a0201b3c2a/numpy-2.4.6-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73", size = 12504263, upload-time = "2026-05-18T23:37:09.715Z" }, +] + +[[package]] +name = "numpy" +version = "2.5.3" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.12' and sys_platform == 'win32'", + "python_full_version >= '3.12' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +sdist = { url = "https://files.pythonhosted.org/packages/13/01/11703282db468b85f6f7b8c7f22d058de5970d5c7e60a3a8aaa313c3de36/numpy-2.5.3.tar.gz", hash = "sha256:df2d5874ff183595a4ba404edd04f6bd9b5505c1d7708573f6a6c17489a67563", size = 20791231, upload-time = "2026-09-06T16:27:47.073Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/50/8fdbb16af64895706a45f06a4068e29db732ec180f3c1375f14123359138/numpy-2.5.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cb189f09db39283b26bfd061ec16189e14f71c6755207f72a0f7540867afe5b9", size = 16994982, upload-time = "2026-09-06T16:24:29.244Z" }, + { url = "https://files.pythonhosted.org/packages/60/39/789131c1188c078dcb3a1692e72e1e050c68b88ffe72c9ccaac9bcd7a9cd/numpy-2.5.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f59a878c33d6b88122d80d239bb3b845d58708750b0cb06a09aebb9b18ec696c", size = 12009327, upload-time = "2026-09-06T16:24:32.491Z" }, + { url = "https://files.pythonhosted.org/packages/9c/59/a312e95696e5f601914dd8b6dd844692ba61670807417e24b68e337b5c70/numpy-2.5.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:a72f874bc9e10e4b8f80426fb49716d5141f64442a0c8418065093ec8017fbb0", size = 5445405, upload-time = "2026-09-06T16:24:35.071Z" }, + { url = "https://files.pythonhosted.org/packages/30/d0/5623a1707ed4fe16e3909fe3cf5ee3da004ae677ad23d83bbf3adf1a6faf/numpy-2.5.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:fc36dc566135b5eceec4cf89758fcb719266a019ef07dae1754ae7c9f617ef3e", size = 6783213, upload-time = "2026-09-06T16:24:37.253Z" }, + { url = "https://files.pythonhosted.org/packages/f1/32/84146fc020ad3c25f805f70ab60da46fe3c540a21369754a7e4369754b6f/numpy-2.5.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:76c2c1e6bfa5c84adc6434dfbf013aa92096a7985221762c8f11fedfd20fff58", size = 15687872, upload-time = "2026-09-06T16:24:39.751Z" }, + { url = "https://files.pythonhosted.org/packages/65/af/aa78d1a88805456e212b65461354cd943197fb9acecc4c90fd12295123a3/numpy-2.5.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7e18c623bb5c95acb3b3328861272816ba199fb531921c5d6d0b675f1fde9e3", size = 16717410, upload-time = "2026-09-06T16:24:42.745Z" }, + { url = "https://files.pythonhosted.org/packages/3b/24/faa79d865e69a97ba17473b23a1b74094b2259c03e820c70297293b9ea49/numpy-2.5.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4f8929ee6c96bfbd7b4ed2032e0c03af86fe1826740ab61ddabf9072d06e57ff", size = 17040975, upload-time = "2026-09-06T16:24:45.961Z" }, + { url = "https://files.pythonhosted.org/packages/62/4a/8877e629445a7176297dffcaf9c485faa96a95d81728a62521ad55bd4c0f/numpy-2.5.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b5d93cf48f687479941d12b69c873ad2cc76bbd487f0091c2200636497f34034", size = 18476479, upload-time = "2026-09-06T16:24:49.35Z" }, + { url = "https://files.pythonhosted.org/packages/c8/db/35e1c2d38b04cbd5b731f9d71495e055e813197669d22b612f11748d2ff9/numpy-2.5.3-cp312-cp312-win32.whl", hash = "sha256:bf63afbe037eb5d2fe87fbcc7778e61da53ebaf21d938a4515aa73b62532a5d4", size = 6133378, upload-time = "2026-09-06T16:24:51.915Z" }, + { url = "https://files.pythonhosted.org/packages/3c/a1/accf6d4f0c80c5d9ba9735d6b1550e444180599f34dec69ca01360f717ad/numpy-2.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:0a59a421a32580a009e8a1751345bf829631b990dc1794b80514ab722b435def", size = 12567828, upload-time = "2026-09-06T16:24:54.255Z" }, + { url = "https://files.pythonhosted.org/packages/22/43/1764aff32e4652526ae2f71fa8b3efd8d25c8a3d6926914454e47138ed1e/numpy-2.5.3-cp312-cp312-win_arm64.whl", hash = "sha256:ccb32e0525d29e8b0572eb84c9a57af0e7a4e615726927506f55063c62414034", size = 10485432, upload-time = "2026-09-06T16:24:57.278Z" }, + { url = "https://files.pythonhosted.org/packages/79/e5/8fb89cd46d14e35699d13bf943a5f5f441ecee8667120a1f6105ab89e349/numpy-2.5.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:66a78fe4556c60aceda5916f9eacd638b18e9e681016ec302dcb4682d6d4d034", size = 16991061, upload-time = "2026-09-06T16:25:00.411Z" }, + { url = "https://files.pythonhosted.org/packages/2f/06/9dc9e48b5e5e941c8b10350c5ff2d721da42a20517d911d15544246775ff/numpy-2.5.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92f30e89b8ee0ecf363033576c422b2f58fed6a80bed0aa48dff6d14c654663e", size = 12003676, upload-time = "2026-09-06T16:25:03.475Z" }, + { url = "https://files.pythonhosted.org/packages/ab/2a/98282aa5b8f58b1157d440bb6282eed47e3632a5de53a714fbab17e659fe/numpy-2.5.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f9a2353b37a1a9e78fd82b27ad7e2a32a2d036604d18f02b05e3136c62ca3b09", size = 5439695, upload-time = "2026-09-06T16:25:05.978Z" }, + { url = "https://files.pythonhosted.org/packages/a1/f9/b6533d777be9d6ffd29dc1be0867e563e6e8cc9a220ff1b716adc317f060/numpy-2.5.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:ccbc4665079665c3cf3bab4db9f6b095370cd6437d66be549b6c2a1fd19e1958", size = 6779395, upload-time = "2026-09-06T16:25:08.599Z" }, + { url = "https://files.pythonhosted.org/packages/73/85/735720d04ec197c5dcfacdfc9922667c7f1f5f496a279b7ba4d7c74c4cc7/numpy-2.5.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c76d5dde9f445058f83d0c02af00557a4db91de9a9a57c0df87d1535001d654b", size = 15681750, upload-time = "2026-09-06T16:25:11.173Z" }, + { url = "https://files.pythonhosted.org/packages/3a/1b/3b16a9bc514a440a7a0883684111dcb1ef1aee960af2ca95da8fc775f124/numpy-2.5.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5fa86b80fd24bcd1aff83ad23be44ea323de3f787be8f8b15d4a65621e25321", size = 16708577, upload-time = "2026-09-06T16:25:14.171Z" }, + { url = "https://files.pythonhosted.org/packages/69/c4/386f397831b07328b639c96c5b62719346cf4baf07c68d927239752b1534/numpy-2.5.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd4cb9ad3c7889b9b3fe0a9a9fb5d2ed26f9879bff2608d9f01aed147a20d231", size = 17042047, upload-time = "2026-09-06T16:25:17.582Z" }, + { url = "https://files.pythonhosted.org/packages/5f/3e/a700ecbf36e85ae8328fd3b0e12eeddc22ed6358a64cb2bd913e0d195d65/numpy-2.5.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1302b90c0e52281681b2975adfe8a860cb7b12216a27b4b0b4207c44bf7bccf0", size = 18465724, upload-time = "2026-09-06T16:25:20.949Z" }, + { url = "https://files.pythonhosted.org/packages/41/ee/38e785e88a4045f6ad1d1f2808dcdfafdca48c760260c0587bf171e29fc9/numpy-2.5.3-cp313-cp313-win32.whl", hash = "sha256:1c80eabb4035ecf4ca9cd49cde8a9fdd69a729e63e6474887d1523ade7aa277f", size = 6129003, upload-time = "2026-09-06T16:25:23.664Z" }, + { url = "https://files.pythonhosted.org/packages/f3/ec/100f2b1794ede74a9b3d7ec6b9736927f56713414c1dfe19ab6c383494bf/numpy-2.5.3-cp313-cp313-win_amd64.whl", hash = "sha256:71cad2b2a7451ab79d8f5e71b453485b6775963d5cf794179144a7463fe6e8ec", size = 12560965, upload-time = "2026-09-06T16:25:26.602Z" }, + { url = "https://files.pythonhosted.org/packages/80/b1/7dc825ca94c12acebbce4c37caa5e198695eb31424bc579679f32b1bb49d/numpy-2.5.3-cp313-cp313-win_arm64.whl", hash = "sha256:8e4dd766076855b5ff7ea52fa5f07ce26286726e0f8bff446b7739d02e6ea204", size = 10482343, upload-time = "2026-09-06T16:25:29.772Z" }, +] + +[[package]] +name = "numpydoc" +version = "1.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c4/2f/5e9bf8ed0a93587b8089242b4926dfd04d4b3b0b65f04345d219a1225f03/numpydoc-1.11.0.tar.gz", hash = "sha256:26db0adaac8087e98da05c86b11198defd962aef7c21f4dffd2703c8c6eb4187", size = 101575, upload-time = "2026-09-15T16:31:08.905Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/e5/f5c38d4899cd8edd5b522071c5658202077d113c3225484d779cf257970e/numpydoc-1.11.0-py3-none-any.whl", hash = "sha256:493ad2ce0d8275ca5da484ec37dbdbbc1334c3a6968dffd10ec729b51753e15e", size = 71464, upload-time = "2026-09-15T16:31:07.521Z" }, +] + +[[package]] +name = "packaging" +version = "26.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/fa/3944b40b07da9ce895c0e6303a5ab7d53da063554f534556b134a54d6093/packaging-26.3.tar.gz", hash = "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79", size = 313412, upload-time = "2026-08-04T18:15:28.737Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c", size = 129956, upload-time = "2026-08-04T18:15:27.159Z" }, +] + +[[package]] +name = "pandas" +version = "3.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "numpy", version = "2.5.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "python-dateutil" }, + { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/be/4f/5f3422a2afec5ffc46308b79e53291365a93748b498ac2e58bead0197916/pandas-3.0.5.tar.gz", hash = "sha256:dca3734d6ab7c906e6730f0788b0a1dbb9f2467731f9711f77995c8e9d62d712", size = 4658219, upload-time = "2026-07-22T22:19:28.819Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/ef/f1fd7431d635bf20015489bf0bd69c17fff1018de773540f651455a3916b/pandas-3.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2946e77e4a53cd248cbde631a12f0e51c8324ce354c3eba4d20147c1ad6f4282", size = 10397178, upload-time = "2026-07-22T22:17:48.274Z" }, + { url = "https://files.pythonhosted.org/packages/31/b4/0eafac990a431561187694126de01f9b12559549b4d86360c0c4bd870fde/pandas-3.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:71ecc8fb7ed1a7aa4392316b5309a6347e8e7f832f38fd897846b3a1457a9298", size = 9990736, upload-time = "2026-07-22T22:17:52.388Z" }, + { url = "https://files.pythonhosted.org/packages/de/21/359880af3ea9b7cb23bea5b51e8e70ef3866c03be09da9a2787e18e330a8/pandas-3.0.5-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b173f5951ff6b8b0ec7675e20dff3c97b7e7a57dfcce387c2d7c5afe87cb7899", size = 10814438, upload-time = "2026-07-22T22:17:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/d1/50/d6cc4d7e508bbccf5d6027314a8312bc7ac73d0ec7f195f53838daafab40/pandas-3.0.5-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2c0cf1dd9b55a22d105fc46c1b489af3bd42264fcba7c66297bf47a9a1d9c78a", size = 11323634, upload-time = "2026-07-22T22:17:56.858Z" }, + { url = "https://files.pythonhosted.org/packages/70/2b/d5f0a8c90dd0ae04e64ba53b871afb796ec026b615086d382ddc2ade729b/pandas-3.0.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0fac0010c75e4efb6b99e249c183a8993ce0dc95c240f9b120a5e67c727b7928", size = 11850860, upload-time = "2026-07-22T22:17:59.1Z" }, + { url = "https://files.pythonhosted.org/packages/5c/30/183aec2e19adf778a98d29b5729a0a68f4cc4ebf9b9c3b70d0297355bcb1/pandas-3.0.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:08d24fe11a17dc33bd6e937dc9c665f9cba08fbdc9f657f405713515febe300d", size = 12411100, upload-time = "2026-07-22T22:18:01.485Z" }, + { url = "https://files.pythonhosted.org/packages/fa/9a/31f4983f191af51ab2a8f2d0c7b33dff3a84da26533f982fff02c2f9e28b/pandas-3.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:b1261758dfb6cf12c3cff8300e21cefad30e7ec709abb4c24ac7318e6a52462a", size = 9968804, upload-time = "2026-07-22T22:18:03.903Z" }, + { url = "https://files.pythonhosted.org/packages/49/97/7886c89a39045c69ad82cbceaf3343810480c8ef49a216319ce8183860a6/pandas-3.0.5-cp311-cp311-win_arm64.whl", hash = "sha256:679f4e85b30ddb1515458ab1e788d3e260eae369b1f78da7a3aa4cac8ebf4a2a", size = 9205447, upload-time = "2026-07-22T22:18:06.134Z" }, + { url = "https://files.pythonhosted.org/packages/1c/54/1dc810ea558d1320b597aa140a514f2fdf1d2ea09c38cf556f13ea712ec9/pandas-3.0.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fa290c16964d4963fbfbc358928239cf3bd755b20e988ce944877def2f44471d", size = 10411717, upload-time = "2026-07-22T22:18:08.307Z" }, + { url = "https://files.pythonhosted.org/packages/68/56/fbe81c09195924d8b7b8d4461a20458fe80a6a5ed6b24f0314da684277e1/pandas-3.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c2e26bb46934b8a2ca0c3de1d3d606fc5f6746584791b2db264d58cf370e08dc", size = 9957095, upload-time = "2026-07-22T22:18:10.6Z" }, + { url = "https://files.pythonhosted.org/packages/e0/51/fac252f4a913ed5eabf3c11b880a9e8d5a6c10f0b2129d0462212d238b4d/pandas-3.0.5-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73fa87b08a7ef706f8aafda39ddaccf2a99047bea62d8c88a0361bcafb2237bc", size = 10485458, upload-time = "2026-07-22T22:18:12.834Z" }, + { url = "https://files.pythonhosted.org/packages/12/98/e976540c1addf70442be7842a18cf70884a964abbf69442504f4d2939989/pandas-3.0.5-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d373ce03ffd84010ed9839fa73672a9c8256990532e158440c0085db7d914b34", size = 10998091, upload-time = "2026-07-22T22:18:15.209Z" }, + { url = "https://files.pythonhosted.org/packages/a4/8c/1f29b5be8d3fc47dd7567eb167fabba2085879b31e0287ce7cba6d3d2ff4/pandas-3.0.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2a29c53d85ea98c5e792c59ef82ee9fbe6ca902c0d0adb6b23f45ef894cd7bf6", size = 11499501, upload-time = "2026-07-22T22:18:17.689Z" }, + { url = "https://files.pythonhosted.org/packages/9d/e2/bd9c98ad2df7b38bde002adde4cdf353519da51881634323b126c55997f9/pandas-3.0.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a5ad3b02ed6bc7d7ae9b70804b2c6aa31827489d150f8e623ce82491b82085d7", size = 12060559, upload-time = "2026-07-22T22:18:20.147Z" }, + { url = "https://files.pythonhosted.org/packages/f3/9a/ffbd852d58bd74a617fe2f8ee6a58a96982271ce41cf981eab22190b4a4b/pandas-3.0.5-cp312-cp312-pyemscripten_2024_0_wasm32.whl", hash = "sha256:b2acb4650527eec6822c3dadb2b771277b65e7dae7a267d4bccf65fd1bb3fbce", size = 7197652, upload-time = "2026-07-22T22:18:22.502Z" }, + { url = "https://files.pythonhosted.org/packages/70/b5/d2d3e9ae73362ba4229651b0ee1455cf78073a1ce585f6ff693782ce263e/pandas-3.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:80a611068e8a3ac23f7398c6c14eb46dc974e5cc9997f653e2dcfd1da74edd41", size = 9831691, upload-time = "2026-07-22T22:18:24.534Z" }, + { url = "https://files.pythonhosted.org/packages/52/51/dea1e89d6a6796b9c43f85a09b484ee03edb8a4c4842e73e200a8c11301c/pandas-3.0.5-cp312-cp312-win_arm64.whl", hash = "sha256:25ff585b972a18ef1fe9ffa3ac6544d9950508aa76832e5147640b6022821e49", size = 9105796, upload-time = "2026-07-22T22:18:27.064Z" }, + { url = "https://files.pythonhosted.org/packages/bf/09/7b95c4a0025227d6f118c4039b423412ac6a982db02864166185d812fbc7/pandas-3.0.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c1c05a767fe8e5b4fe9e1c29806829c582052eaedb9120a3da83ba3f69e24a5b", size = 10385742, upload-time = "2026-07-22T22:18:29.346Z" }, + { url = "https://files.pythonhosted.org/packages/8d/0c/dc78fd8c4da477b4b5e8ad37295af352190d21ef63a9ee1bc071753074cc/pandas-3.0.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b86765f268b56f7e665b93bce9d5df69dee7f99e595cf8fb839483ab315942a3", size = 9932067, upload-time = "2026-07-22T22:18:31.833Z" }, + { url = "https://files.pythonhosted.org/packages/3e/71/3592c055cf44df9808550f9368ceda80ff2b224d355ef73fe251dcda1802/pandas-3.0.5-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c597ecf5616b5c420372c1d4d4c00dbbfba7398bea857dcc984347e1ea48417b", size = 10466756, upload-time = "2026-07-22T22:18:34.195Z" }, + { url = "https://files.pythonhosted.org/packages/e3/70/4363150359f95b4cb4bcbb34ca23572bb5495749a621a8f3d5a1ddfd293c/pandas-3.0.5-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4b11c36e218331d0387cbe3a0a5f75162357a1d92d57b2b08a336ff94b19b2be", size = 10938525, upload-time = "2026-07-22T22:18:36.81Z" }, + { url = "https://files.pythonhosted.org/packages/f7/d0/317e7a0c67c0e69fa905a0161409397a7dc2d46ff611f6ca4803352c042b/pandas-3.0.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cf52e1f61d229496da17dc7ab54acdee627357e7008fd4fecba3d0ba2937fa58", size = 11489303, upload-time = "2026-07-22T22:18:39.287Z" }, + { url = "https://files.pythonhosted.org/packages/f1/8d/36dade89b49e4f9d5cbdbe863772581f98c0c6d78fc39ad4c557f6f2e17e/pandas-3.0.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:db172144bb56422bd157812f3b021eacc255451470b31e2c633c349490a1cfee", size = 11989004, upload-time = "2026-07-22T22:18:42.208Z" }, + { url = "https://files.pythonhosted.org/packages/9c/ba/18c4ec8a746e177da05a9e7a7963781d8ea195780724f854601b6ebd6b78/pandas-3.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:0d298e951f23016ce4699951d044ae6418dbc91bf68cefca0f77666fcbb4e5c6", size = 9826896, upload-time = "2026-07-22T22:18:44.539Z" }, + { url = "https://files.pythonhosted.org/packages/de/ec/28a57266b753799a87b8bc79e7887ac6fd981b8c6d2978a0b7e7b6bd708c/pandas-3.0.5-cp313-cp313-win_arm64.whl", hash = "sha256:66266d3442a5e8b3c90274c2b8b230bee42dd1c286bc822cc2f9f2c7e12b883e", size = 9094790, upload-time = "2026-07-22T22:18:47.468Z" }, +] + +[[package]] +name = "pandocfilters" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/70/6f/3dd4940bbe001c06a65f88e36bad298bc7a0de5036115639926b0c5c0458/pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e", size = 8454, upload-time = "2024-01-18T20:08:13.726Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc", size = 8663, upload-time = "2024-01-18T20:08:11.28Z" }, +] + +[[package]] +name = "parso" +version = "0.8.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/4b/90c937815137d43ce71ba043cd3566221e9df6b9c805f24b5d138c9d40a7/parso-0.8.7.tar.gz", hash = "sha256:eaaac4c9fdd5e9e8852dc778d2d7405897ec510f2a298071453e5e3a07914bb1", size = 401824, upload-time = "2026-05-01T23:13:02.138Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/5d/8268b644392ee874ee82a635cd0df1773de230bde356c38de28e298392cc/parso-0.8.7-py2.py3-none-any.whl", hash = "sha256:a8926eb2a1b915486941fdbd31e86a4baf88fe8c210f25f2f35ecec5b574ca1c", size = 107025, upload-time = "2026-05-01T23:12:58.867Z" }, +] + +[[package]] +name = "pexpect" +version = "4.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" }, +] + +[[package]] +name = "pillow" +version = "12.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/3d/bb7fca845737cf9d7dbde16ed1843984665ff2e0a518f5db43e77ec540b9/pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce", size = 47025035, upload-time = "2026-07-01T11:56:38.965Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/c8/0a78b0e02d7ac54bc03e5321c9220da52f0c2ea83b21f7c40e7f3169c502/pillow-12.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:00808c5e14ef63ac5161091d242999076604ff74b883423a11e5d7bbb38bf756", size = 5392415, upload-time = "2026-07-01T11:53:47.162Z" }, + { url = "https://files.pythonhosted.org/packages/b2/5b/a02d30018abd97ced9f5a6c63d28597694a00d066516b9c1c6de45859fc9/pillow-12.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37d6d0a00072fd2948eb22bce7e1475f34569d90c87c59f7a2ec59541b77f7a6", size = 4785266, upload-time = "2026-07-01T11:53:49.079Z" }, + { url = "https://files.pythonhosted.org/packages/c8/98/766667a4be768150a202836acd9fad19c06824ca86c4286d3cf6b274964e/pillow-12.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bcb46e2f9feff8d06323983bd83ed00c201fdcab3d74973e7072a889b3979fcd", size = 6263814, upload-time = "2026-07-01T11:53:51.32Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2d/ede717bc1144f63886c21fd349bb95860b0d1a21149ff16f2bb362b612b6/pillow-12.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23d27a3e0307ec2244cc51e7287b919aa68d097504ebe19df4e76a98a3eea5bd", size = 6934408, upload-time = "2026-07-01T11:53:53.487Z" }, + { url = "https://files.pythonhosted.org/packages/a3/48/9c58b685e69d49c31af6c8eb9012055fab7e665785165c84796e2c73ce72/pillow-12.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4f883547d4b7f0495ebe7056b0cc2aea76094e7a4abc8e933540f3271df27d9c", size = 6337160, upload-time = "2026-07-01T11:53:55.457Z" }, + { url = "https://files.pythonhosted.org/packages/ff/fa/dc2a5c0ba6df93f67c31d34b808b7ce440b40cdbf96f0b81cde1d1e6fa93/pillow-12.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:236ff70b9312fb68943c703aa842ca6a758abfa45ac187a5e7c1452e96ef72b5", size = 7045172, upload-time = "2026-07-01T11:53:57.736Z" }, + { url = "https://files.pythonhosted.org/packages/86/a5/444817a4d4c4c2417df00513086ca196f388d8f9ef40c2e4ccd1ad1af54b/pillow-12.3.0-cp311-cp311-win32.whl", hash = "sha256:10e41f0fbf1eec8cfd234b8fe17a4caac7c9d0db4c204d3c173a8f9f6ef3232b", size = 6472232, upload-time = "2026-07-01T11:53:59.767Z" }, + { url = "https://files.pythonhosted.org/packages/63/c6/4bad1b18d132a50b27e1365e1ab163616f7a5bb56d330f66f9d1d9d4f9d4/pillow-12.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8e95e1385e4998ae9694eeaa4730ba5457ff61185b3a55e2e7bea0880aef452a", size = 7233653, upload-time = "2026-07-01T11:54:02.066Z" }, + { url = "https://files.pythonhosted.org/packages/fd/16/00f91ab7760dc842f5aad55217e80fc4a7067a0604535249bc8a2d6d9870/pillow-12.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:ebaea975e03d3141d9d3a507df75c9b3ec90fa9d2ffd07567b3a978d9d790b26", size = 2568195, upload-time = "2026-07-01T11:54:04.622Z" }, + { url = "https://files.pythonhosted.org/packages/37/bf/fb3ebff8ddcb76aac5a01389251bbbb9519922a9b520d8247c1ca864a25d/pillow-12.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ba09209fbe443b4acccebe845d8a138b89a8f4fbaeedd44953490b5315d5e965", size = 5345969, upload-time = "2026-07-01T11:54:06.397Z" }, + { url = "https://files.pythonhosted.org/packages/d8/66/9a386a92561f402389a4fc70c18838bf6d35eb5eb5c6850b4b2dc64f5048/pillow-12.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffd0c5368496f41b0944be820fcb7a838aa6e623d250b01acf2643939c3f99d7", size = 4780323, upload-time = "2026-07-01T11:54:09.351Z" }, + { url = "https://files.pythonhosted.org/packages/25/27/ac8f99618ffd3dde21db0f4d4b1d2ab00c0880595bfd17df103f7f39fd0c/pillow-12.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9c7f76c0673154f044e9d78c8655fb4213f6ca31a836df48b40fe5d187717b9", size = 6266838, upload-time = "2026-07-01T11:54:11.71Z" }, + { url = "https://files.pythonhosted.org/packages/84/21/a35af28dcc61f37ed850a2d64c65c701321dfbf25085e469d5559360cbbf/pillow-12.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:78cb2c6865a35ab8ff8b75fd122f6033b92a62c82801110e48ddd6c936a45d91", size = 6940830, upload-time = "2026-07-01T11:54:13.732Z" }, + { url = "https://files.pythonhosted.org/packages/eb/51/8b08617af3ad95e33ce6d7dd2c99ed6c8298f7fb131636303956be022e25/pillow-12.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e491916b378fba47242221bb9ead245211b70d504f495d105d17b14a24b4907c", size = 6344383, upload-time = "2026-07-01T11:54:15.756Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/cf78ac9780bb93c28328f408973845a309d4d145041665f734572ced1b52/pillow-12.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0dd2064cbc55aaec028ef5fbb60fa47bb6c3e7918e07ff17935284b227a9d2df", size = 7052934, upload-time = "2026-07-01T11:54:17.721Z" }, + { url = "https://files.pythonhosted.org/packages/20/20/25e0f4dc178a6bc0696793720055519a0de89e7661dae886992decbd2f81/pillow-12.3.0-cp312-cp312-win32.whl", hash = "sha256:dbce0b29841537a2fa4a214c2bbf14de3587c9680caa9b4e217568472490b28f", size = 6472684, upload-time = "2026-07-01T11:54:19.839Z" }, + { url = "https://files.pythonhosted.org/packages/45/89/da2f7971a317f83d807fdd4065c0af40208e59e692cc43d315a71a0e96d1/pillow-12.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a2b55dd6b2a4c4b7d87ffa56bdb33fdc5fdb9a462173861a7bc097f17d91cb09", size = 7227137, upload-time = "2026-07-01T11:54:22.025Z" }, + { url = "https://files.pythonhosted.org/packages/de/47/4845a0a6c0dbf1db8456bd9fc791f13c5ced7ced20606d08a0aacfd25b49/pillow-12.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:331b624368d4f1d069149002f25f44bc61c8919ce8ddb3c45bdad8f6e2d89510", size = 2568267, upload-time = "2026-07-01T11:54:24.051Z" }, + { url = "https://files.pythonhosted.org/packages/9d/ac/31fb64e1e7efb5a4b50cd3d92049ba89ac6e4d8d3bb6a74e15048ca3353e/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:21900ce7ba264168cd50defae43cd75d25c833ad4ad6e73ffc5596d12e25ac89", size = 4161684, upload-time = "2026-07-01T11:54:25.934Z" }, + { url = "https://files.pythonhosted.org/packages/87/b4/9805e23d2b4d77842b468513841fda254ee42f0289d25088340e4ff46e2d/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:4e8c2a84d977f50b9daed6eeaf3baef67d00d5d74d932288f02cb94518ee3ace", size = 4255487, upload-time = "2026-07-01T11:54:27.935Z" }, + { url = "https://files.pythonhosted.org/packages/df/39/ecf519435a200c693fe053a6ee4d835b41cf963a4dfc2551c4e637cb2a71/pillow-12.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:ae26d61dfa7a47befdc7572b521024e8745f3d809bd95ca9505a7bba9ef849ec", size = 3696433, upload-time = "2026-07-01T11:54:29.813Z" }, + { url = "https://files.pythonhosted.org/packages/42/92/2fc3ffad878ae8dd5469ec1bc8eb83b71f48e13efdf68f02709003982a32/pillow-12.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7a743ff716f746fc19a9557f60dab1600d4613255f8a7aeb3cdde4db7eb15a66", size = 5345889, upload-time = "2026-07-01T11:54:31.97Z" }, + { url = "https://files.pythonhosted.org/packages/10/76/8803c13605b763d33d156c4678fc77f8443389c0c51c8aef707bb02015f4/pillow-12.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d69141514cc30b774ceea5e3ed3a6635c8d8a96edf664689b890f4089111fb35", size = 4780109, upload-time = "2026-07-01T11:54:34.026Z" }, + { url = "https://files.pythonhosted.org/packages/1f/01/e18aff37cb0b4aac47ac90f016d347a49aca667ef97f190b06ac2aabc928/pillow-12.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f7401aebd7f581d7f83a439d87d474999317ee099218e5ad25d125290990ba65", size = 6263736, upload-time = "2026-07-01T11:54:36.131Z" }, + { url = "https://files.pythonhosted.org/packages/f7/62/de5bdd77d935331f4f802edc11e4d82950f642caad6cb2f949837b8560e2/pillow-12.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0847a763afefb695bc912d7c131e7e0632d4edc1d8698f58ddabec8e46b8b6d3", size = 6937129, upload-time = "2026-07-01T11:54:38.216Z" }, + { url = "https://files.pythonhosted.org/packages/70/4d/105627a13300c5e0df1d174230b32fd1273062c96f7745fd552b945d1e1d/pillow-12.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:571b9fcb07b97ef3a492028fb3d2dc0993ca23a06138b0315286566d29ef718a", size = 6339562, upload-time = "2026-07-01T11:54:40.354Z" }, + { url = "https://files.pythonhosted.org/packages/6b/1d/f13de01a553988ab895ba1c722e06cf3144d4f57656fd5b81b6d881f1179/pillow-12.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:756c768d0c9c2955feb7a56c37ea24aea2e369f8d36a88da270b6a9f19e62b5e", size = 7049439, upload-time = "2026-07-01T11:54:42.489Z" }, + { url = "https://files.pythonhosted.org/packages/c9/f9/066794cca041b969964f779ee5fa66a9498bbf34248ac39c5d7954e4198f/pillow-12.3.0-cp313-cp313-win32.whl", hash = "sha256:a876864214e136f0eb367788dbd7df045f4806801518e2cfe9e13229cfe06d8f", size = 6473287, upload-time = "2026-07-01T11:54:44.9Z" }, + { url = "https://files.pythonhosted.org/packages/a6/9b/7a58e61d62be561da3a356fe2384d4059a6345fc130e23ef1c36a5b81d24/pillow-12.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:1cca606cd25738df4ed873d5ad46bbdb3d83b5cbca291f6b4ff13a4df6b0bbe8", size = 7239691, upload-time = "2026-07-01T11:54:47.141Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b0/c4ed4f0ef8f8fa5ee8351537db6650bb8189f7e118842978dd6589065692/pillow-12.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:b629de27fda84b42cde7edef0d85f13b958b47f6e9bbcbba9b673c562a89bd8b", size = 2568185, upload-time = "2026-07-01T11:54:49.137Z" }, + { url = "https://files.pythonhosted.org/packages/75/18/2e8b40223153ccbc60df07f9e8928dc0c76202aa4e55ae9f53962b6510d6/pillow-12.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b3c777e849237620b022f7f297dd67705f9f5cf1685f09f02e46f93e92725468", size = 5302510, upload-time = "2026-07-01T11:56:25.736Z" }, + { url = "https://files.pythonhosted.org/packages/46/3e/51fabf59d5ab801ceab709453d3ab6b180083496579549de4c45ced6528a/pillow-12.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:b343699e8308bdc51978310e1c959c584e7869cc8c40780058c87da7781a1e94", size = 4736058, upload-time = "2026-07-01T11:56:28.041Z" }, + { url = "https://files.pythonhosted.org/packages/bf/20/22fe9384b7949e25fb1293bcfc84fb82590ff4ea6b37c95b24d26d793d86/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbd139c8447d25dd750ab79ee274cc5e1fe80fc56340ab10b18a195e1b6eca3e", size = 5237776, upload-time = "2026-07-01T11:56:30.263Z" }, + { url = "https://files.pythonhosted.org/packages/08/14/f6ba68107680ffa74b39985f3f30884e41318fbc4250caa423c79b4788bb/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e7e480451b9fa137494bccd3a7d69adbe8ac65a87d97be61e11f1b1050a5bac3", size = 5860358, upload-time = "2026-07-01T11:56:32.68Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0169bc772ec491108b62f644f8ecf1fe5d8ae5ebafde2ee2142210166903/pillow-12.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:04f01d28a6aaff387bf842a13be313df23ba0597a44f1a976c9feb3c6ff4711a", size = 7231786, upload-time = "2026-07-01T11:56:35.046Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.11.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/53/18/f3bb8ef0d3b930692343da8aa4d3cbcd6749477c053959395ac81965a6e9/platformdirs-4.11.8.tar.gz", hash = "sha256:f23abafea7dd4276d1f29104b83598d7dcc567cafd07c9c951e66665645437fc", size = 37182, upload-time = "2026-09-08T22:20:42.866Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/e1/5b7b8bbb55084d1425bcb9bc823ff519e1b2be05f6ebb0089e2eacc38413/platformdirs-4.11.8-py3-none-any.whl", hash = "sha256:52f2f181bbfde907966932cc8312d967d02976422d66d537ea16092b8e291081", size = 24027, upload-time = "2026-09-08T22:20:41.537Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pre-commit" +version = "4.6.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/74/89/1f3e8e1fc3e97de0fa963495832f581f025f29471602a309e48808244292/pre_commit-4.6.2.tar.gz", hash = "sha256:8f5d7bfb021ecdbcd9d49d89847082dd24172ccde534390081a679ad046e2441", size = 198670, upload-time = "2026-08-10T22:07:18.421Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/45/e2/bbb7129c9e7999a6b8ee9cca3b66486c25c423ab5a75f34071798b74ce94/pre_commit-4.6.2-py2.py3-none-any.whl", hash = "sha256:e2dde9a75d3bce11bd3831c26d134df00a2803c1d818be6a0383c3dcda25dc4e", size = 226202, upload-time = "2026-08-10T22:07:16.942Z" }, +] + +[[package]] +name = "prompt-toolkit" +version = "3.0.53" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/ea/39b988c938f75cb75d7045b5c69f8bfed47ee2152c8837fb403de29d6fb8/prompt_toolkit-3.0.53.tar.gz", hash = "sha256:9ec8a0ad96d5c56148b3f914aa79c1564c3fde5d2e6b876e7bc327e353cf8fa6", size = 435492, upload-time = "2026-07-26T20:56:14.758Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/6f/84908cad2d6aa5144abcf7b42709fe4fdb459bc640ec7ac5786e7693dabc/prompt_toolkit-3.0.53-py3-none-any.whl", hash = "sha256:01c0891d7f9237d5e339f7d3e42cdae80b7534abb1c7c0e3352efba6231492f2", size = 392288, upload-time = "2026-07-26T20:56:12.512Z" }, +] + +[[package]] +name = "psutil" +version = "7.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/08/510cbdb69c25a96f4ae523f733cdc963ae654904e8db864c07585ef99875/psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b", size = 130595, upload-time = "2026-01-28T18:14:57.293Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f5/97baea3fe7a5a9af7436301f85490905379b1c6f2dd51fe3ecf24b4c5fbf/psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea", size = 131082, upload-time = "2026-01-28T18:14:59.732Z" }, + { url = "https://files.pythonhosted.org/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63", size = 181476, upload-time = "2026-01-28T18:15:01.884Z" }, + { url = "https://files.pythonhosted.org/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312", size = 184062, upload-time = "2026-01-28T18:15:04.436Z" }, + { url = "https://files.pythonhosted.org/packages/16/ba/0756dca669f5a9300d0cbcbfae9a4c30e446dfc7440ffe43ded5724bfd93/psutil-7.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b", size = 139893, upload-time = "2026-01-28T18:15:06.378Z" }, + { url = "https://files.pythonhosted.org/packages/1c/61/8fa0e26f33623b49949346de05ec1ddaad02ed8ba64af45f40a147dbfa97/psutil-7.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9", size = 135589, upload-time = "2026-01-28T18:15:08.03Z" }, + { url = "https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486", size = 129090, upload-time = "2026-01-28T18:15:22.168Z" }, + { url = "https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979", size = 129859, upload-time = "2026-01-28T18:15:23.795Z" }, + { url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560, upload-time = "2026-01-28T18:15:25.976Z" }, + { url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997, upload-time = "2026-01-28T18:15:27.794Z" }, + { url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972, upload-time = "2026-01-28T18:15:29.342Z" }, + { url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266, upload-time = "2026-01-28T18:15:31.597Z" }, + { url = "https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988", size = 137737, upload-time = "2026-01-28T18:15:33.849Z" }, + { url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" }, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" }, +] + +[[package]] +name = "pure-eval" +version = "0.2.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/9f/abfd2959e9261dd5217ca8551d4de211ca6ab26fe9b72cf44731ff6c4442/pure_eval-0.2.4.tar.gz", hash = "sha256:260c2774686e651b79f8b8e7fc9d80b3599ea6a66334b47d5f4abb69fc2c0ea1", size = 20563, upload-time = "2026-09-10T21:41:22.836Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/18/83376915176eb058cb86470eb7396388a13350b09a8f233a79303bbcbc5b/pure_eval-0.2.4-py3-none-any.whl", hash = "sha256:96cae060a313cfaad51bb761278bfb0e62dc0248d9315a81173752dc546cd37a", size = 11893, upload-time = "2026-09-10T21:41:21.532Z" }, +] + +[[package]] +name = "pycparser" +version = "3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, +] + +[[package]] +name = "pydata-sphinx-theme" +version = "0.21.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "accessible-pygments" }, + { name = "babel" }, + { name = "beautifulsoup4" }, + { name = "docutils" }, + { name = "jinja2" }, + { name = "pygments" }, + { name = "requests" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bd/ac/692035c97b732b26ee269fb14ec790046b21c7383a46bedfb3d40c3a4884/pydata_sphinx_theme-0.21.0.tar.gz", hash = "sha256:dc3f71216ea34725ddad68e505497eab4ba134a88abfb971a7df6b28a35c1997", size = 5010490, upload-time = "2026-08-25T14:16:47.949Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/8d/fb90c2ada1a938ba55f1730139f4d43736aee22d5f82f927c64cd858256f/pydata_sphinx_theme-0.21.0-py3-none-any.whl", hash = "sha256:d36a754bf9580b01789efa8a01869f2d7c87fa6c543ecbcafb14b6bdd4364f90", size = 6208465, upload-time = "2026-08-25T14:16:46.223Z" }, +] + +[[package]] +name = "pydot" +version = "4.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/35/b17cb89ff865484c6a20ef46bf9d95a5f07328292578de0b295f4a6beec2/pydot-4.0.1.tar.gz", hash = "sha256:c2148f681c4a33e08bf0e26a9e5f8e4099a82e0e2a068098f32ce86577364ad5", size = 162594, upload-time = "2025-06-17T20:09:56.454Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/32/a7125fb28c4261a627f999d5fb4afff25b523800faed2c30979949d6facd/pydot-4.0.1-py3-none-any.whl", hash = "sha256:869c0efadd2708c0be1f916eb669f3d664ca684bc57ffb7ecc08e70d5e93fee6", size = 37087, upload-time = "2025-06-17T20:09:55.25Z" }, +] + +[[package]] +name = "pyformlang" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "networkx" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "numpy", version = "2.5.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "pydot" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/57/c9/ab842f57e0f9cade8c0b3d07e461f1faeb6ba1e3a52b5d199378f19443b5/pyformlang-1.0.1.tar.gz", hash = "sha256:7135f281ab59e77136483a8e7803e1ef692933f903372a2c373d69b7da2aef5f", size = 83865, upload-time = "2022-06-03T13:13:26.245Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/1c/2fc222ec68fff2149071de0499d2ad8fb5ede594281e95c4339a0783c6fb/pyformlang-1.0.1-py3-none-any.whl", hash = "sha256:ae2d4c2a7ddd56ce84f23e54c522fb03ef433a381d46961442aca6d0850e4f1c", size = 113819, upload-time = "2022-06-03T13:13:24.089Z" }, +] + +[[package]] +name = "pygments" +version = "2.21.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c", size = 5005329, upload-time = "2026-08-17T08:02:48.824Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pyright" +version = "1.1.414" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nodeenv" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e1/1b/244c7b710031ada80f27e579ec20d28a2285dfc318fed0339866b1047f12/pyright-1.1.414.tar.gz", hash = "sha256:523c0a97c60da6333234955c277730c9cf4f5bd6d5399e7b7d2b0fc5d3599524", size = 4154638, upload-time = "2026-09-10T12:26:53.181Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/ba/18b6e682ead424ad24bcc134339ae5d1b931cd9ae260540592a058a91279/pyright-1.1.414-py3-none-any.whl", hash = "sha256:2a6b4b3298c9eec174c5ed83bd338de6eee82df2992f3e1930e6199d381be36f", size = 6225049, upload-time = "2026-09-10T12:26:51.427Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "pytest-cov" +version = "7.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", extra = ["toml"] }, + { name = "pluggy" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/51/a849f96e117386044471c8ec2bd6cfebacda285da9525c9106aeb28da671/pytest_cov-7.1.0.tar.gz", hash = "sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2", size = 55592, upload-time = "2026-03-21T20:11:16.284Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" }, +] + +[[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, upload-time = "2024-03-01T18:36:20.211Z" } +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, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "python-discovery" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/91/96/0f93e27c9f60a650838f2118159aa115fd5732c0716247917b7ba7ede665/python_discovery-1.6.0.tar.gz", hash = "sha256:6393b4eae1be8b2182670635e7baff89ac21cb9f8e86fd1ff40c7b1144febb4c", size = 82849, upload-time = "2026-08-28T17:30:02.366Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/5e/21abf578182fb15006a57faf3711a1e659e29d600d19b6e557eae908c81d/python_discovery-1.6.0-py3-none-any.whl", hash = "sha256:d4e244cf17b8b29819ed78003d55fbacf86eda23425b075454fff9271b79377a", size = 38451, upload-time = "2026-08-28T17:30:01.236Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, +] + +[[package]] +name = "pyzmq" +version = "27.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "implementation_name == 'pypy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e7/8d/5b3d5631c2f4b4b8862f64cd0c9eb777b5710eeb5125b4be8dd0a200a4c0/pyzmq-27.2.0.tar.gz", hash = "sha256:54d4259d1bfae24ecdb5ca79f7acc2eac6c286a02d6a0ae617797cb45f0726d3", size = 292316, upload-time = "2026-08-20T19:08:21.19Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/2e/8897afa4538707d86645f51cc50e66b2b84900edb1be9dc9af2c2fc04e5d/pyzmq-27.2.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:9216132843d139a123f243c07fe70f7487dce5041093dd77040f9adb5dc91872", size = 1457109, upload-time = "2026-08-20T19:06:26.022Z" }, + { url = "https://files.pythonhosted.org/packages/d1/bc/dbce7bc1654fa25b1e68b9bad9e547906f581ce919c186a88ed951cb794c/pyzmq-27.2.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:d41ebb260b69329b7d4a2936d44c872c86dd785355b51366c8b14e07ed7e9373", size = 985701, upload-time = "2026-08-20T19:06:27.481Z" }, + { url = "https://files.pythonhosted.org/packages/95/cf/6981738b57c83fef33f356141ad83bf51e92f2f70c9d5767affd1a699f07/pyzmq-27.2.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:468139ddb2e494d06e586bd3a6835077e8b3764560c8db552fe685c5867fc24e", size = 714285, upload-time = "2026-08-20T19:06:28.962Z" }, + { url = "https://files.pythonhosted.org/packages/50/b5/13657961a845e29c28a4e7ac4202999ec90b3bba1890a5469ce2ae90359d/pyzmq-27.2.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:39755dc4a923021bd0677990ffdbc21cff0e1ee1cf07fe3817acea153ef4cb67", size = 888465, upload-time = "2026-08-20T19:06:30.4Z" }, + { url = "https://files.pythonhosted.org/packages/58/5a/ca7ee7a767413d4ba858e93748b95e30b35b8c139849fba94de4433ea2e5/pyzmq-27.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:714f8cbd66c7e405338d668f79d2fe83fe923defe348e843be998603cf92eeff", size = 1705731, upload-time = "2026-08-20T19:06:31.819Z" }, + { url = "https://files.pythonhosted.org/packages/0b/8b/083f6184e4eba566c9a3cc9974b1b0fe327b7093788135ba8133edaa67a6/pyzmq-27.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1132805970045adb9f5f05dd57040978286a8e21a5475f2c2ddf1bc983b9a2c7", size = 2074243, upload-time = "2026-08-20T19:06:33.36Z" }, + { url = "https://files.pythonhosted.org/packages/57/f5/249362b664ae725d534c8843214fa9fd7fccd74532a19e24603954a88a7d/pyzmq-27.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b26f2d0493b79ce3c3112c8a12649418915582ba4707b8ed9f44febf2be71f42", size = 1926859, upload-time = "2026-08-20T19:06:34.796Z" }, + { url = "https://files.pythonhosted.org/packages/bf/cc/23c613c15f06d879f13364d14c17e5e4e8304049411e96c1410e6e56c3ea/pyzmq-27.2.0-cp311-cp311-win32.whl", hash = "sha256:44f261eca7dfb9904ea2b56428f59ab693bbe2715c0413a701f17b067ebf877c", size = 570747, upload-time = "2026-08-20T19:06:36.337Z" }, + { url = "https://files.pythonhosted.org/packages/dc/bc/bbbcf89003c93f18e33665c26e3c48d75e3915c3dd22887f3a7aea2c5e26/pyzmq-27.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:8b86e04f55af0f4d8cd8ecf14c0b8b81ebc8fd66fa20126b753514628ecadc7e", size = 644845, upload-time = "2026-08-20T19:06:37.711Z" }, + { url = "https://files.pythonhosted.org/packages/14/c5/4635d0ba2b8493edf6d5541fff0b07fa1d986fdfc29c596a53a21e20f9af/pyzmq-27.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:917d601e9540098f580d2723d0ce6402cdb6f02bc8dc2de74e0dca6e13bffd1b", size = 567495, upload-time = "2026-08-20T19:06:39.246Z" }, + { url = "https://files.pythonhosted.org/packages/57/8a/153532fa53db30e116118164f3af269a1f3966b3e2ba32c89b12fe864bd8/pyzmq-27.2.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:591c8de5851c5ea372194469fe97587b97c3b641e9a70f31bb3474acbfde0241", size = 1431074, upload-time = "2026-08-20T19:06:40.601Z" }, + { url = "https://files.pythonhosted.org/packages/c8/ef/c08b91248bb90a9efa81fa00ba81b69c157c74d0c5efbb2c319d91babb62/pyzmq-27.2.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:00e73942ef12cecbc7951c4a9104bb8ffaed742abb13af2da6833d90dd368cef", size = 973915, upload-time = "2026-08-20T19:06:42.037Z" }, + { url = "https://files.pythonhosted.org/packages/b4/78/a3a3a86c2b00fadb92ece1ca4f8f028d62b2ce9ac3526097239ab2d6fba9/pyzmq-27.2.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f8079d0521fe94bbb401fe9407578b28f3701627c8be2c9f7e0c5b77dcb0109", size = 697722, upload-time = "2026-08-20T19:06:43.325Z" }, + { url = "https://files.pythonhosted.org/packages/62/2c/d5828306f795e8d34676d266823b74e2101e0ad3760d12083de3e02abbb2/pyzmq-27.2.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dea74fd65f1fc5f7fe167916a473ebe6ed6174e5e5d9de11ea6583661be6cf43", size = 872258, upload-time = "2026-08-20T19:06:44.627Z" }, + { url = "https://files.pythonhosted.org/packages/09/52/51253b78fd8739293e283407eeecb14215c02c71b6519af21f6eed8e69cd/pyzmq-27.2.0-cp312-abi3-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dcc99ca132b667a4ed750afd42db4ea73288f18425a9b2e3c0af095665c491f5", size = 739591, upload-time = "2026-08-20T19:06:46.214Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3e/142c85b67a4c9678629b0cf6d5125b29663d75be69bfaa57a3cac344d780/pyzmq-27.2.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b8d5f66e4a8246cf77f7b8f7902af64f00553368fa0373c89d99b78f0ad79394", size = 1689031, upload-time = "2026-08-20T19:06:47.612Z" }, + { url = "https://files.pythonhosted.org/packages/0e/ee/0776fb0f98ed1eb74d77240087fef0ab045b6ad15cb09555c6c5134c98ad/pyzmq-27.2.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:d1526b42a2e725b84ed226f37becedc250c6347594e5ed304e4e9aff68c9aec3", size = 2059547, upload-time = "2026-08-20T19:06:49.064Z" }, + { url = "https://files.pythonhosted.org/packages/aa/0e/ec77f691a4aebe29ab6329f996fb0e0270c876a3016086e3ca6ef733bcae/pyzmq-27.2.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f707bcf2c1d007d14d70531d4dd7b41060881c73efa845580bf6faaf9ea24d42", size = 1910457, upload-time = "2026-08-20T19:06:50.783Z" }, + { url = "https://files.pythonhosted.org/packages/30/97/1f5530ff4fc271b4597048371d5af972c2baab51be132ba15874e0327a6a/pyzmq-27.2.0-cp312-abi3-win32.whl", hash = "sha256:fdaaa4ea3242f6ad298eb5177eb042aea5c73c30e76d20caee7b15af20d24ec2", size = 563450, upload-time = "2026-08-20T19:06:52.307Z" }, + { url = "https://files.pythonhosted.org/packages/02/8b/b83f7780dad22e0878e4c7bd9158ebd24ed12bc3d5e3a471cd0576f77ded/pyzmq-27.2.0-cp312-abi3-win_amd64.whl", hash = "sha256:2c218c6ab8bc447ba62054b581fd30209689d199c6ecb253f79615ca74a38e12", size = 628633, upload-time = "2026-08-20T19:06:53.809Z" }, + { url = "https://files.pythonhosted.org/packages/52/aa/3918b5ac7f9987bd9c421b065074fd7409ded88f856f2c704a24341877ec/pyzmq-27.2.0-cp312-abi3-win_arm64.whl", hash = "sha256:348d6fd3e4b81ae4580622ea8c2ea60224e84b2ac1b3be4482e6edc7de06e7a3", size = 556006, upload-time = "2026-08-20T19:06:55.242Z" }, + { url = "https://files.pythonhosted.org/packages/83/5e/d0541596b48c5a19f85dcbea83d6673d8e91681cdf853eb194c31fc9766e/pyzmq-27.2.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:c551b9e2f86dc625fcb1a032c0d68042678caf96a8dd7c28796766b673bd5b52", size = 1127193, upload-time = "2026-08-20T19:06:56.545Z" }, + { url = "https://files.pythonhosted.org/packages/50/9f/8c7411bb283982d46e6d56dca6a095678c87eb0398daead12776d9881ac2/pyzmq-27.2.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:288cc790da0e3064a14a38ddc56ba169dada8c8af4cb86518db2bcbd380eedbb", size = 1166833, upload-time = "2026-08-20T19:06:58.011Z" }, + { url = "https://files.pythonhosted.org/packages/93/22/7187a1f0bf2b8bf8dc6b91762438fb9b472f684f2dc4cb74a24bf8957943/pyzmq-27.2.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a7c1144dc61777938e932a2c9011b980b89fd8ff3733033b34c44c299187a6e1", size = 875015, upload-time = "2026-08-20T19:08:01.692Z" }, + { url = "https://files.pythonhosted.org/packages/92/71/09b71620ad52bad4eb68b1516978ecaf52ef623c3fa16e0732a03cf3274c/pyzmq-27.2.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:c218b816220d05acf6ab1bafca58926d95cbcc5fec5024724666030466308f0c", size = 774395, upload-time = "2026-08-20T19:08:03.108Z" }, + { url = "https://files.pythonhosted.org/packages/9c/cf/5c8eb9994a14ff5ee5b0cada339421748746c95aee0280c8b656741e8749/pyzmq-27.2.0-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:ae6ebbc0bfe5a21ce21e32ba567bf73df2d93888109c65acbd42506cf9395759", size = 877994, upload-time = "2026-08-20T19:08:04.724Z" }, + { url = "https://files.pythonhosted.org/packages/97/64/e22094c5555e550b6450ecfcceb6a1205d893d9a18ae27764c8c45acfb16/pyzmq-27.2.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:679b5b1dde326a921ea2c9ec1f9ea3115bfe1b4735779bbc6eb0473a0ed93f71", size = 614492, upload-time = "2026-08-20T19:08:06.487Z" }, + { url = "https://files.pythonhosted.org/packages/d2/28/5b1042899caed18278c56d54a502f5254d463afe8aea1acbecc98e053391/pyzmq-27.2.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f5c6d8744d10b5e1eadd90a7c58f8546acf6bf680ee463f7e6ada09ad6c9f802", size = 780574, upload-time = "2026-08-20T19:08:07.987Z" }, + { url = "https://files.pythonhosted.org/packages/77/a3/f134603a671c114c6b56eb912bba890f09e2d43b8a28d243be5a5507cf2f/pyzmq-27.2.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3ee8dd7031d5e23f632e0e7eee67183ca7d2536e0de35dc1e5d69f3471a791e8", size = 553961, upload-time = "2026-08-20T19:08:09.651Z" }, +] + +[[package]] +name = "rdflib" +version = "7.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/f5/18bb77b7af9526add0c727a3b2048959847dc5fb030913e2918bf384fec3/rdflib-7.6.0.tar.gz", hash = "sha256:6c831288d5e4a5a7ece85d0ccde9877d512a3d0f02d7c06455d00d6d0ea379df", size = 4943826, upload-time = "2026-02-13T07:15:55.938Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/c2/6604a71269e0c1bd75656d5a001432d16f2cc5b8c057140ec797155c295e/rdflib-7.6.0-py3-none-any.whl", hash = "sha256:30c0a3ebf4c0e09215f066be7246794b6492e054e782d7ac2a34c9f70a15e0dd", size = 615416, upload-time = "2026-02-13T07:15:46.487Z" }, +] + +[[package]] +name = "referencing" +version = "0.37.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" }, +] + +[[package]] +name = "requests" +version = "2.34.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed", size = 142856, upload-time = "2026-05-14T19:25:27.735Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" }, +] + +[[package]] +name = "roman-numerals" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/f9/41dc953bbeb056c17d5f7a519f50fdf010bd0553be2d630bc69d1e022703/roman_numerals-4.1.0.tar.gz", hash = "sha256:1af8b147eb1405d5839e78aeb93131690495fe9da5c91856cb33ad55a7f1e5b2", size = 9077, upload-time = "2025-12-17T18:25:34.381Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl", hash = "sha256:647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7", size = 7676, upload-time = "2025-12-17T18:25:33.098Z" }, +] + +[[package]] +name = "rpds-py" +version = "2026.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/2a/9618a122aeb2a169a28b03889a2995fe297588964333d4a7d67bdf46e147/rpds_py-2026.6.3.tar.gz", hash = "sha256:1cebd1337c242e4ec2293e541f712b2da849b29f48f0c293684b71c0632625d4", size = 64051, upload-time = "2026-06-30T07:17:53.009Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/1f/a2dca5ffdbf1d475ffc4e80e4d5d720ff3a00f691795910116960ee12511/rpds_py-2026.6.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:7b689145a1485c335569bd056464f3243a29af7ed3871c7be31ad624ba239bc7", size = 342174, upload-time = "2026-06-30T07:14:54.821Z" }, + { url = "https://files.pythonhosted.org/packages/4d/dc/323d08583c0832911768663d1944f0107fcd4088704858d84b5e06d105a0/rpds_py-2026.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:db08f45aecde626498fb3df07bcf6d2ec040af42e859a4f5040d79c200342911", size = 345513, upload-time = "2026-06-30T07:14:56.515Z" }, + { url = "https://files.pythonhosted.org/packages/0b/2a/e31989834d18d2f26ec1d2774c5b1eb3331df4ea8ada525175294c94b48a/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:acc992ab27b15f852c76755eb2ab7dce86585ddadba6fa5946e58556088845b4", size = 373783, upload-time = "2026-06-30T07:14:57.736Z" }, + { url = "https://files.pythonhosted.org/packages/87/fe/e80107ee3639585c9941c17d6a42cd65325022f656c023191fce78c324c8/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f88d653e7b3b779d71ae7454e20dcc9b6bae903f33c269db9f2be41bda3f261", size = 378316, upload-time = "2026-06-30T07:14:59.077Z" }, + { url = "https://files.pythonhosted.org/packages/22/6f/81e3adf81acfb6fa694de2a6e4e7d8863121e3e0799e0a7725e6cf5679c4/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e52655eaf81e32593abedaa4bfe33170c8cfedf3365ed9be6e11e07f148f0278", size = 499423, upload-time = "2026-06-30T07:15:00.488Z" }, + { url = "https://files.pythonhosted.org/packages/2d/9a/41263969df0ce3d9af2a96d5005a288200af1989aed3354bfceb5fc0b21f/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dfcc8b909769d19db55c7cc9541eb64b9b774b1057ffffb4f1048070475bb9f9", size = 386077, upload-time = "2026-06-30T07:15:01.911Z" }, + { url = "https://files.pythonhosted.org/packages/5e/19/7e98f468bd50346faff5b10e5297374b443bfdddacc8e9fbc65984539597/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c1255b302953c86a486b81d330d5ee1d5bd937691ce271b6be0ef0e299eaab7", size = 371315, upload-time = "2026-06-30T07:15:03.317Z" }, + { url = "https://files.pythonhosted.org/packages/99/3c/2b973b4d371906a134b03decfea7f5d9835a2c6d263454392e15b64b5b18/rpds_py-2026.6.3-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:8d2294a31386bfa251d8c8a39472beee17db67d4f1a6eabea665d35c9a4461c3", size = 383502, upload-time = "2026-06-30T07:15:04.627Z" }, + { url = "https://files.pythonhosted.org/packages/98/2a/12e2799500af0a307bca76b63361c51f9fe479223561489c29eea1f2ee41/rpds_py-2026.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8f23ead891a3b762f35ab3b04623da7056545b48aa60d59957e6789914545da", size = 402673, upload-time = "2026-06-30T07:15:05.856Z" }, + { url = "https://files.pythonhosted.org/packages/2d/e3/21e5872d165fe08be4f229e3d5ee9d90019c0bf0e5538de60dbd54009450/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:421aba32367055614287a4292b6a17f1939c9452299f7a0209c117e990b646d4", size = 549964, upload-time = "2026-06-30T07:15:07.159Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d0/5ee0fe36844297de8123bee27bc12078c1a7416ad9f1b8a8ca18d6b0c0ac/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1e5822dfc2f0d4ab7e745eaa6d85945069329beeccef965af3f3bb26058fcab6", size = 615446, upload-time = "2026-06-30T07:15:08.531Z" }, + { url = "https://files.pythonhosted.org/packages/b1/80/1ea5873cb683f2fbe5f21b23ea1f6d179ead19f3c5b249b7eb5dca568ef2/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:83e35b57523816c8613fd0776b40cd8bb9f596b37ddd2692eb4a6bb5ab2f8c93", size = 576975, upload-time = "2026-06-30T07:15:09.97Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e1/90ef639217a5ddb15b7f4f61b1c33911fd044ad03c311bafdd2bcab85582/rpds_py-2026.6.3-cp311-cp311-win32.whl", hash = "sha256:de3eceba0b683bcbb1ab93da016d0270df1f9ae7be716b40214c5dafac6ea45a", size = 204453, upload-time = "2026-06-30T07:15:11.324Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b7/b7a1695d7af36f521fb11e80d6d3adbd744f73b921859bd3c2a2c0dc706f/rpds_py-2026.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:2c54a076ca4d370980ab57bc0e31df57bbe8d41340436a90ef8b1219a3cbb127", size = 223219, upload-time = "2026-06-30T07:15:12.476Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a2/145afacf796e4506062825941176ad9445c2dcf2b3b6a1f13d3030a15e19/rpds_py-2026.6.3-cp311-cp311-win_arm64.whl", hash = "sha256:168c733a7112e071bb7a66460e667edfcff06c017a3c523f7a8a8e08d0140804", size = 219137, upload-time = "2026-06-30T07:15:13.631Z" }, + { url = "https://files.pythonhosted.org/packages/5c/be/2e8974163072e7bab7df1a5acd54c4498e75e35d6d18b864d3a9d5dadc92/rpds_py-2026.6.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a0811d33247c3d6128a3001d763f2aa056bb3425204335400ac54f89eec3a0d0", size = 343691, upload-time = "2026-06-30T07:15:14.96Z" }, + { url = "https://files.pythonhosted.org/packages/a4/73/319dfa745dd668efe89309141ded489126461fcecd2b8f3a3cda185129b6/rpds_py-2026.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:538949e262e46caa31ac01bdb3c1e8f642622922cacbabbae6a8445d9dc33eaf", size = 338542, upload-time = "2026-06-30T07:15:16.267Z" }, + { url = "https://files.pythonhosted.org/packages/21/63/4239893be1c4d09b709b1a8f6be4188f0870084ff547f46606b8a75f1b03/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55927d532399c2c646100ff7feb48eaa940ad70f42cd68e1328f3ded9f81ca24", size = 368180, upload-time = "2026-06-30T07:15:17.62Z" }, + { url = "https://files.pythonhosted.org/packages/1c/ca/9c5de382225234ceb37b1844ebdb140db12b2a278bb9efe2fcd19f6c82ce/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f56f1695bc5c0871cbc33dc0130fcf503aab0c57dcc5a6700a4f49eba4f2652e", size = 375067, upload-time = "2026-06-30T07:15:18.952Z" }, + { url = "https://files.pythonhosted.org/packages/87/dc/863f69d1bf04ade34b7fe0d59b9fdf6f0135fe2d7cbca74f1d665589559d/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:270b293dae9058fc9fcedab50f13cebf46fb8ed1d1d54e0521a9da5d6b211975", size = 490509, upload-time = "2026-06-30T07:15:20.434Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ef/eac16a12048b45ec7c7fa94f2be3438a5f26bf9cc8580b18a1cfd609b7f6/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:127565fead0a10943b282957bd5447804ff3160ad79f2ad2635e6d249e380680", size = 382754, upload-time = "2026-06-30T07:15:21.831Z" }, + { url = "https://files.pythonhosted.org/packages/04/8f/d2f3f532616be4d06c316ef119683e832bd3d41e112bf3a88f4151c95b17/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecabd69db66de867690f9797f2f8fa27ba501bbc24540cbdbdc649cd15888ba6", size = 366189, upload-time = "2026-06-30T07:15:23.371Z" }, + { url = "https://files.pythonhosted.org/packages/e3/29/41a7b0e98a4b44cd676ab7598419623373eb43b20be68c084935c1a8cf88/rpds_py-2026.6.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:58eadac9cd119677b60e1cf8ac4052f35949d71b8a9e5556efccbe82533cf22a", size = 377750, upload-time = "2026-06-30T07:15:24.659Z" }, + { url = "https://files.pythonhosted.org/packages/2e/05/ecda0bec46f9a1565090bcdc941d023f6a25aff85fda28f89f8d19878152/rpds_py-2026.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7491ee23305ac3eb59e492b6945881f5cd77a6f731061a3f25b77fd40f9e99a4", size = 395576, upload-time = "2026-06-30T07:15:25.987Z" }, + { url = "https://files.pythonhosted.org/packages/68/a8/6ed52f03ee6cb854ce78785cc9a9a672eb880e83fd7224d471f667d151f1/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2c99f7e8ccb3dd6e3e4bfeac657a7b208c9bac8075f4b078c02d7404c34107fa", size = 543807, upload-time = "2026-06-30T07:15:27.356Z" }, + { url = "https://files.pythonhosted.org/packages/8f/d6/156c0d3eea27ba09b92562ba2364ba124c0a061b199e17eac637cd25a5e2/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:62698275682bf121181861295c9181e789030a2d516071f5b8f3c23c170cd0fc", size = 611187, upload-time = "2026-06-30T07:15:28.931Z" }, + { url = "https://files.pythonhosted.org/packages/f1/31/774212ed989c62f7f310220089f9b0a3fb8f40f5443d1727abd5d9f52bc9/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a214c993455f99a89aaeadc9b21241900037adc9d97203e374d75513c5911822", size = 573030, upload-time = "2026-06-30T07:15:30.553Z" }, + { url = "https://files.pythonhosted.org/packages/c9/50/22f73127a41f1ce4f87fe39aadfb9a126345801c274aa93ae88456249327/rpds_py-2026.6.3-cp312-cp312-win32.whl", hash = "sha256:501f9f04a588d6a09179368c57071301445191767c64e4b52a6aa9871f1ef5ed", size = 202185, upload-time = "2026-06-30T07:15:32.027Z" }, + { url = "https://files.pythonhosted.org/packages/04/3a/f0ee4d4dde9d3b69dedf1b5f74e7a40017046d55052d173e418c6a94f960/rpds_py-2026.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:2c958bf94822e9290a40aaf2a822d4bc5c88099093e3948ad6c571eca9272e5f", size = 220394, upload-time = "2026-06-30T07:15:33.359Z" }, + { url = "https://files.pythonhosted.org/packages/f3/83/3382fe37f809b59f02aac04dbc4e765b480b46ee0227ed516e3bdc4d3dfc/rpds_py-2026.6.3-cp312-cp312-win_arm64.whl", hash = "sha256:22bffe6042b9bcb0822bcd1955ec00e245daf17b4344e4ed8e9551b976b63e96", size = 215753, upload-time = "2026-06-30T07:15:34.778Z" }, + { url = "https://files.pythonhosted.org/packages/a4/9e/b818ee580026ec578138e961027a68820c40afeb1ec8f6819b54fb99e196/rpds_py-2026.6.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3cfe765c1da0072636ca06628261e0ea05688e160d5c8a03e0217c3854037223", size = 343012, upload-time = "2026-06-30T07:15:36.005Z" }, + { url = "https://files.pythonhosted.org/packages/f3/6b/686d9dc4359a8f163cfbbf89ee0b4e586431de22fe8248edb63a8cf50d49/rpds_py-2026.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f4d78253f6996be4901669ad25319f842f740eccf4d58e3c7f3dd39e6dde1d8f", size = 338203, upload-time = "2026-06-30T07:15:37.462Z" }, + { url = "https://files.pythonhosted.org/packages/9e/9b/069aa329940f8207615e091f5eedbbd40e1e15eac68a0790fd05ccdf796c/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54f45a148e28767bf343d33a684693c70e451c6f4c0e9904709a723fafbdfc1f", size = 367984, upload-time = "2026-06-30T07:15:39.008Z" }, + { url = "https://files.pythonhosted.org/packages/14/db/34c203e4becff3703e4d3bc121842c00b8689197f398161203a880052f4e/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:842e7b070435622248c7a2c44ae53fa1440e073cc3023bc919fed570884097a7", size = 374815, upload-time = "2026-06-30T07:15:40.253Z" }, + { url = "https://files.pythonhosted.org/packages/ee/7d/8071067d2cc453d916ad836e828c943f575e8a44612537759002a1e07381/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8020133a74bd81b4572dd8e4be028a6b1ebcd70e6726edc3918008c08bee6ee6", size = 490545, upload-time = "2026-06-30T07:15:41.729Z" }, + { url = "https://files.pythonhosted.org/packages/a3/42/da06c5aa8f0484ff07f270787434204d9f4535e2f8c3b51ed402267e63c3/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cdc7e35386f3847df728fbcb5e887e2d79c19e2fa1eba9e51b6621d23e3243af", size = 382828, upload-time = "2026-06-30T07:15:43.327Z" }, + { url = "https://files.pythonhosted.org/packages/57/d7/fe978efc2ae50abe48eb7464668ea99f53c010c60aeebb7b35ad27f23661/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acac386b453c2516111b50985d60ce46e7fadb5ea71ae7b25f4c946935bf27cf", size = 365678, upload-time = "2026-06-30T07:15:44.992Z" }, + { url = "https://files.pythonhosted.org/packages/69/9d/1d8922e1990b2a6eb532b6ff53d3e73d2b3bbffc84116c75826bee73dfc6/rpds_py-2026.6.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:425560c6fa0415f27261727bb20bd097568485e5eb0c121f1949417d1c516885", size = 377811, upload-time = "2026-06-30T07:15:46.523Z" }, + { url = "https://files.pythonhosted.org/packages/b1/3d/198dceafb4fb034a6a47347e1b0735d34e0bd4a50be4e898d408ee66cb14/rpds_py-2026.6.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a550fb4950a06dde3beb4721f5ad4b25bf4513784665b0a8522c792e2bd822a4", size = 395382, upload-time = "2026-06-30T07:15:47.955Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f1/13968e49655d40b6b19d8b9140296bbc6f1d86b3f0f6c346cf9f1adddf4b/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f4bca01b63096f606e095734dd56e74e175f94cfbf24ff3d63281cec61f7bb7", size = 543832, upload-time = "2026-06-30T07:15:49.33Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ab/289bcb1b90bd3e40a2900c561fa0e2087345ecbb094f0b870f2345142b7c/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ccffae9a092a00deb7efd545fe5e2c33c33b88e7c054337e9a74c179347d0b7d", size = 611011, upload-time = "2026-06-30T07:15:50.847Z" }, + { url = "https://files.pythonhosted.org/packages/1e/16/5043105e679436ccfbc8e5e0dd2d663ed18a8b8113515fd06a5e5d77c83e/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1cf01971c4f2c5553b772a542e4aaf191789cd331bc2cd4ff0e6e65ba49e1e97", size = 572431, upload-time = "2026-06-30T07:15:52.394Z" }, + { url = "https://files.pythonhosted.org/packages/85/ed/adab103321c0a6565d5ae1c2998349bc3ee175b82ccc5ae8fc04cc413075/rpds_py-2026.6.3-cp313-cp313-win32.whl", hash = "sha256:8c3d1e9c15b9d51ca0391e13da1a25a0a4df3c58a37c9dc368e0736cf7f69df0", size = 201710, upload-time = "2026-06-30T07:15:53.894Z" }, + { url = "https://files.pythonhosted.org/packages/7b/ed/a03b09668e74e5dabbf2e211f6468e1820c0552f7b0500082da31841bf7b/rpds_py-2026.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:9250a9a0a6fd4648b3f868da8d91a4c52b5811a62df58e753d50ae4454a36f80", size = 219454, upload-time = "2026-06-30T07:15:55.25Z" }, + { url = "https://files.pythonhosted.org/packages/27/17/b8642c12930b71bc2b25831f6708ccf0f75abcd11883932ec9ce54ba3a78/rpds_py-2026.6.3-cp313-cp313-win_arm64.whl", hash = "sha256:900a67df3fd1660b035a4761c4ce73c382ea6b35f90f9863c36c6fd8bf8b09bb", size = 215063, upload-time = "2026-06-30T07:15:56.573Z" }, + { url = "https://files.pythonhosted.org/packages/b4/9c/f0d19ac587fd0e4ab6b72cda355e9c5a6166b01ef7e064e437aef8eb9fef/rpds_py-2026.6.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:4cf2d36a2357e4d07bb5a4f98801265327b48256867816cfd2ceb001e9754a8f", size = 349791, upload-time = "2026-06-30T07:17:33.315Z" }, + { url = "https://files.pythonhosted.org/packages/38/c7/1d49d204c9fd2ee6c537601dc4c1ba921e03363ca576bfab94a00254ac9a/rpds_py-2026.6.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:30c6dc199b24a5e3e81d50da0f00858c5bbdb2617a750395687f4339c5818171", size = 352842, upload-time = "2026-06-30T07:17:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/ac/e5/c0b5dc93cd0d4c06ce1f438907649514e2ea077bcd911e3154a51e96c38e/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9891e594296ab9dada6551c8e7b387b2721f27a67eecd528412e8906247a7b90", size = 382094, upload-time = "2026-06-30T07:17:36.514Z" }, + { url = "https://files.pythonhosted.org/packages/0d/54/ec0e907b4ca8d541112db352409bd15f871c9b243e0c92c9b5a46ae96f01/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5c2dc92304aa48a4a60443b548bb12f12e119d4b72f314015e67b9e1be97fca", size = 388662, upload-time = "2026-06-30T07:17:38.235Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f4/921c22a4fd0f1c1ac13a3996ffbf0aa67951e2c8ad0d1d9574938a2932e8/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:127e08c0642d880cf32ca47ec2a4a77b901f7e2dd1ad9762adb13955d72ffcc9", size = 504896, upload-time = "2026-06-30T07:17:39.689Z" }, + { url = "https://files.pythonhosted.org/packages/0b/1b/a114b972cefa1ab1cdb3c7bb177cd3844a12826c507c722d3a73516dbbaf/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8bb68f03f395eb793220b45c097bd4d8c32944393da0fad8b999efac0868fc8c", size = 391545, upload-time = "2026-06-30T07:17:41.336Z" }, + { url = "https://files.pythonhosted.org/packages/4e/98/af9b3db77d47fcbe6c8c1f36e2c2147ec70292819e99c325f871584a1c11/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3450b693fde92133e9f51060568a4c31fcca76d5e53bbd611e689ca446517e9", size = 380059, upload-time = "2026-06-30T07:17:42.857Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ba/0efd8668b97c1d26a61566386c636a7a7a09829e474fdf807caa15a2c844/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:5e8d07bddee435a2ff6f1920e18feff28d0bc4533e42f4bf6927fbd073312c41", size = 393235, upload-time = "2026-06-30T07:17:44.637Z" }, + { url = "https://files.pythonhosted.org/packages/62/90/8c139ee9690f73b0829f32647de6f40d826f8f443af6fa72644f96351aac/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3a83ae6c67b7676b9878378547ca8e93ed77a580037bcbcd1d32f739e1e6089c", size = 413008, upload-time = "2026-06-30T07:17:46.225Z" }, + { url = "https://files.pythonhosted.org/packages/9c/97/0043896fdd7828ce09a1d9a8b06433714d0960fc4ff3fc4aa72b666b764e/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2bfd04c19ddbd6640de0b51894d764bd2758854d5b75bd102d2ef10cb9c293a9", size = 558118, upload-time = "2026-06-30T07:17:47.759Z" }, + { url = "https://files.pythonhosted.org/packages/f6/40/02355f0e134f783a8f9814c4680a1bd311d37671577a5964ea838573ff37/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:ca6546b66be9dc4738b1b043d5ebd5488c66c578c5ff0fd0e8065313fe3afb76", size = 623138, upload-time = "2026-06-30T07:17:49.355Z" }, + { url = "https://files.pythonhosted.org/packages/10/85/48f0abdcef5cce4e034c7a5b0ceeceba0b01bf0d942824f4bb720afe2dec/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:8e65860d238379ed982fd9ba690579b5e95af2f4840f99c772816dbe573cb826", size = 586486, upload-time = "2026-06-30T07:17:51.141Z" }, +] + +[[package]] +name = "ruff" +version = "0.16.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/bb/5a449b9162e49b139d72f61672bd3ac1d790221f796d3304e2241fff4c58/ruff-0.16.7.tar.gz", hash = "sha256:5f71d004ac1263b22fa39462ac5ae618a4b77d58981af2cc79bf79a29c12b1a6", size = 4924184, upload-time = "2026-09-10T18:04:06.336Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/b2/c80aeeb7f9e469c0d63a85d2f1ab6e1ebfbe10ea7a8d2438b7e09e3ff09e/ruff-0.16.7-py3-none-linux_armv6l.whl", hash = "sha256:727307773e7c7f9181d3ed3a2484186e56c1fa1874255911c74585eb2c7c19f9", size = 10048917, upload-time = "2026-09-10T18:03:30.28Z" }, + { url = "https://files.pythonhosted.org/packages/7b/96/20bb7bcae008004df52afcb7ac83432d4a467f2c17b672fe46d26be231c5/ruff-0.16.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9d61c258deabf58f34c67bd4bb4d939c7f2e6b5f0e59c1cdd1cf771b11cde929", size = 10242929, upload-time = "2026-09-10T18:03:32.706Z" }, + { url = "https://files.pythonhosted.org/packages/90/b2/f184b0d5abec02db69cfd7e49b688ae0237554528ca777136c613bf36bee/ruff-0.16.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7ab81118df8945e0193d0240712aa4496573595b75185c3636ed825592a0f728", size = 9847245, upload-time = "2026-09-10T18:03:34.509Z" }, + { url = "https://files.pythonhosted.org/packages/eb/2d/db1633a641866ed801e34cc6b60ef236c5e16f9b2124ab1d49cc24a5fe4f/ruff-0.16.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c196c968874fc8019da8e7163de7a1a370f111e2309b4b7dfea0fce950198d0", size = 9961780, upload-time = "2026-09-10T18:03:36.618Z" }, + { url = "https://files.pythonhosted.org/packages/4d/98/edea21e1a3e38dbbc3bf6bb068b863b3b06184cf8533a4c7dbbe208a89d5/ruff-0.16.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac8c3bd0a7e10ad31e6ce51e7a99f3cb772e69aecdd6b9ea7e99b362f62a62c0", size = 9866337, upload-time = "2026-09-10T18:03:38.805Z" }, + { url = "https://files.pythonhosted.org/packages/0b/11/a15e60d4c87b214646f116ca9d204475bf993ee1047459bc9a360fd4d6d1/ruff-0.16.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:398d3988edde000b5c75dc1b3f584708da9bc990de069c18909142580fec1af9", size = 10562512, upload-time = "2026-09-10T18:03:40.71Z" }, + { url = "https://files.pythonhosted.org/packages/29/42/eaff4c9b6d0c7cdf56df313a17e89ae854f5bbc0b0c8f9cce19be0ab7a8f/ruff-0.16.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce05b62b770a8217c4646a9c4139fca00efe8fe5d71f87df2b243ff20d4584d1", size = 11302938, upload-time = "2026-09-10T18:03:42.607Z" }, + { url = "https://files.pythonhosted.org/packages/5d/43/c75aa59a4ec181fe2ec06cab30e198c1c6d107229a9f008ae3a7c16cabd8/ruff-0.16.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af1b576fddb9d9ef2ececfb5fadcd6a624b25070ed85e3cfcfe449fc3ff6a7b9", size = 10840857, upload-time = "2026-09-10T18:03:44.604Z" }, + { url = "https://files.pythonhosted.org/packages/21/33/81f3da371942ea031105ba679d8d6e28ec1660ccd690a45f42d381161356/ruff-0.16.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ce7f8f22df67c93ed96c717f9128eadb797144ac2bad475cf536f31d6100c55", size = 10370001, upload-time = "2026-09-10T18:03:46.706Z" }, + { url = "https://files.pythonhosted.org/packages/fa/0b/6345fb4dbf6dd0ed1cfe5d18391dc9c3f59cc81622a7b0a65b84b3e730ba/ruff-0.16.7-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:06d0e93d04f392996435ebd600c153f65b47d73fbec2415aa99c5ee5756b3a5f", size = 10548735, upload-time = "2026-09-10T18:03:48.658Z" }, + { url = "https://files.pythonhosted.org/packages/3f/4d/c5576adf511f92a328e5569dda190ecdd430da51f1a649f3a4a2fd73e21e/ruff-0.16.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:142151a5e7b93c1b11111337142f89dd2fbfee92161225c99a97222f22e32656", size = 10108496, upload-time = "2026-09-10T18:03:50.563Z" }, + { url = "https://files.pythonhosted.org/packages/ff/8c/667d83c16199a17a56adc6b0bd4c3beb5b767a2babcd16a56f76f9be7fd6/ruff-0.16.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e6651f97a342d8b35d54d8991544ca22169b86dc54111cb604666940c431b750", size = 9860136, upload-time = "2026-09-10T18:03:52.621Z" }, + { url = "https://files.pythonhosted.org/packages/99/75/78d401106731999a1dd20cc5a6961e37e1eb9397a3b589f73f3a5ce146a3/ruff-0.16.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ef140c6eb935fa9a84c9c607dfb2cb1b85843c192e79265b0c54f35f557ea8e5", size = 10286290, upload-time = "2026-09-10T18:03:55.207Z" }, + { url = "https://files.pythonhosted.org/packages/68/49/56f9c3a8b755df93a0ad318b2147bf4ef5dae9a7e5ec61c460109c67957f/ruff-0.16.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:53e39506a730fadeee0d998ed5946f30671f0db240c6c7c73bdabbe33604bb6f", size = 10745048, upload-time = "2026-09-10T18:03:57.299Z" }, + { url = "https://files.pythonhosted.org/packages/5f/ea/7f9b938a63ece4bec677ad7f9f7fa02df3383db1949ed93a382441c09a87/ruff-0.16.7-py3-none-win32.whl", hash = "sha256:2ea3470fcebcbc5df2fb0c6f3b90333fa9084c534e0111c038fa4a6ab9f1c4b7", size = 10059082, upload-time = "2026-09-10T18:03:59.632Z" }, + { url = "https://files.pythonhosted.org/packages/39/11/480a6973a927aa653e1cead6a6416008640e03a99d05b34c0434b8c6c366/ruff-0.16.7-py3-none-win_amd64.whl", hash = "sha256:7ac26aca826e9e21d0f1cb25b54ac660760a9fdd094d3e4df9848232be98cfc6", size = 10593368, upload-time = "2026-09-10T18:04:01.999Z" }, + { url = "https://files.pythonhosted.org/packages/8b/4b/51327018d056f0dad2c2238f26d1fb0f53707a9d91b75dea6d1b3039f136/ruff-0.16.7-py3-none-win_arm64.whl", hash = "sha256:aab7f39e2c9df6c596216070f98eef1207b94f8516cca20c808826974971855b", size = 10412401, upload-time = "2026-09-10T18:04:04.098Z" }, +] + +[[package]] +name = "s3transfer" +version = "0.19.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "botocore" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/43/35e4d8aa320bffe8287fe8f65f578fa2d2db0a64212f0e710dce58267854/s3transfer-0.19.2.tar.gz", hash = "sha256:ba0309fd86be3c27dbf78cdd813c13c5e1df16e5874b99d2535ebbdfb9892993", size = 165592, upload-time = "2026-07-22T19:30:44.432Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/e7/5c595c75e9f41a44f30e526eda465ea0b4eec93470e074e4a111b253f13a/s3transfer-0.19.2-py3-none-any.whl", hash = "sha256:d8168eccca828cbb2cd573675333f3bddd254313a9c42494b84c76b539e8ba25", size = 90216, upload-time = "2026-07-22T19:30:43.251Z" }, +] + +[[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, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "snowballstemmer" +version = "3.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/f8/0a71edf031f03c40db17503cb8ca78a69a171254e568e7db241b0ab57ea1/snowballstemmer-3.1.1.tar.gz", hash = "sha256:e07bbc54a0d798fe6010a12398422e62a8bfbba95c394fd0956ef58cb4d3e260", size = 123314, upload-time = "2026-06-03T00:56:40.194Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4c/07/2ebca9b11fb9be7340a818d8d6f63feaebb146be2c4afbd6061701d6df6e/snowballstemmer-3.1.1-py3-none-any.whl", hash = "sha256:7e207fa178741da09cdee59d3ecec3827ad5f92b1fc5c9ff3755b639f71f5752", size = 104164, upload-time = "2026-06-03T00:56:38.614Z" }, +] + +[[package]] +name = "soupsieve" +version = "2.9.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/69/99/a6ca3beb3ccacb41fb3321d8a60e5566f9e6467601ef8eba6a17e1b89778/soupsieve-2.9.2.tar.gz", hash = "sha256:4a55d8cf158a9c2e587fa4922f1bbb91d68ac829e2d6f25403a85747c71daf74", size = 122445, upload-time = "2026-08-07T00:57:24.801Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/dc/ad025c1ee131eba60c69f4dd5779b18fcf1e6b21a343e2162a84d5d133c7/soupsieve-2.9.2-py3-none-any.whl", hash = "sha256:8089a26fd974ca7a1f30276d3d8492ab266ab15af581642dfe8aa162e0c1c823", size = 37370, upload-time = "2026-08-07T00:57:23.524Z" }, +] + +[[package]] +name = "sphinx" +version = "9.0.4" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.12' and sys_platform == 'win32'", + "python_full_version < '3.12' and sys_platform == 'emscripten'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils" }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "roman-numerals" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/50/a8c6ccc36d5eacdfd7913ddccd15a9cee03ecafc5ee2bc40e1f168d85022/sphinx-9.0.4.tar.gz", hash = "sha256:594ef59d042972abbc581d8baa577404abe4e6c3b04ef61bd7fc2acbd51f3fa3", size = 8710502, upload-time = "2025-12-04T07:45:27.343Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/3f/4bbd76424c393caead2e1eb89777f575dee5c8653e2d4b6afd7a564f5974/sphinx-9.0.4-py3-none-any.whl", hash = "sha256:5bebc595a5e943ea248b99c13814c1c5e10b3ece718976824ffa7959ff95fffb", size = 3917713, upload-time = "2025-12-04T07:45:24.944Z" }, +] + +[[package]] +name = "sphinx" +version = "9.1.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.12' and sys_platform == 'win32'", + "python_full_version >= '3.12' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils" }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "roman-numerals" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cd/bd/f08eb0f4eed5c83f1ba2a3bd18f7745a2b1525fad70660a1c00224ec468a/sphinx-9.1.0.tar.gz", hash = "sha256:7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb", size = 8718324, upload-time = "2025-12-31T15:09:27.646Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/f7/b1884cb3188ab181fc81fa00c266699dab600f927a964df02ec3d5d1916a/sphinx-9.1.0-py3-none-any.whl", hash = "sha256:c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978", size = 3921742, upload-time = "2025-12-31T15:09:25.561Z" }, +] + +[[package]] +name = "sphinx-copybutton" +version = "0.5.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/2b/a964715e7f5295f77509e59309959f4125122d648f86b4fe7d70ca1d882c/sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd", size = 23039, upload-time = "2023-04-14T08:10:22.998Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/48/1ea60e74949eecb12cdd6ac43987f9fd331156388dcc2319b45e2ebb81bf/sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e", size = 13343, upload-time = "2023-04-14T08:10:20.844Z" }, +] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", size = 20053, upload-time = "2024-07-29T01:09:00.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", size = 119300, upload-time = "2024-07-29T01:08:58.99Z" }, +] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", size = 12967, upload-time = "2024-07-29T01:09:23.417Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", size = 82530, upload-time = "2024-07-29T01:09:21.945Z" }, +] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9", size = 22617, upload-time = "2024-07-29T01:09:37.889Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", size = 98705, upload-time = "2024-07-29T01:09:36.407Z" }, +] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787, upload-time = "2019-01-21T16:10:16.347Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071, upload-time = "2019-01-21T16:10:14.333Z" }, +] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", size = 17165, upload-time = "2024-07-29T01:09:56.435Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", size = 88743, upload-time = "2024-07-29T01:09:54.885Z" }, +] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d", size = 16080, upload-time = "2024-07-29T01:10:09.332Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072, upload-time = "2024-07-29T01:10:08.203Z" }, +] + +[[package]] +name = "sphinxtesters" +version = "0.2.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/aa/08/93af63fc5c6fd4c66b84a92c0048c5d2134fd168c6d763b01a476a3496f1/sphinxtesters-0.2.4.tar.gz", hash = "sha256:09c456e1cd61ec99b64851e2990d2152fdf05bb53d87f3b294f22d73f939d6ca", size = 11354, upload-time = "2024-10-30T11:49:41.116Z" } + +[[package]] +name = "stack-data" +version = "0.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asttokens" }, + { name = "executing" }, + { name = "pure-eval" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, +] + +[[package]] +name = "texext" +version = "0.6.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a6/73/5dc7e7955e4c5a45de3ef1467cfe498233cc3aba2a3c50ff41a55d667c42/texext-0.6.8.tar.gz", hash = "sha256:6c3ccc5578f93a1bd0051fcba25e92d259620d3d9c9031738570e7d78603e7a3", size = 41658, upload-time = "2025-11-10T23:23:32.173Z" } + +[[package]] +name = "tinycss2" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/ae/2ca4913e5c0f09781d75482874c3a95db9105462a92ddd303c7d285d3df2/tinycss2-1.5.1.tar.gz", hash = "sha256:d339d2b616ba90ccce58da8495a78f46e55d4d25f9fd71dfd526f07e7d53f957", size = 88195, upload-time = "2025-11-23T10:29:10.082Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/45/c7b5c3168458db837e8ceab06dc77824e18202679d0463f0e8f002143a97/tinycss2-1.5.1-py3-none-any.whl", hash = "sha256:3415ba0f5839c062696996998176c4a3751d18b7edaaeeb658c9ce21ec150661", size = 28404, upload-time = "2025-11-23T10:29:08.676Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704, upload-time = "2026-03-25T20:21:10.473Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454, upload-time = "2026-03-25T20:21:12.036Z" }, + { url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561, upload-time = "2026-03-25T20:21:13.098Z" }, + { url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824, upload-time = "2026-03-25T20:21:14.569Z" }, + { url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227, upload-time = "2026-03-25T20:21:15.712Z" }, + { url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859, upload-time = "2026-03-25T20:21:17.001Z" }, + { url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204, upload-time = "2026-03-25T20:21:18.079Z" }, + { url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084, upload-time = "2026-03-25T20:21:18.978Z" }, + { url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285, upload-time = "2026-03-25T20:21:20.309Z" }, + { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924, upload-time = "2026-03-25T20:21:21.626Z" }, + { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018, upload-time = "2026-03-25T20:21:23.002Z" }, + { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948, upload-time = "2026-03-25T20:21:24.04Z" }, + { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341, upload-time = "2026-03-25T20:21:25.177Z" }, + { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159, upload-time = "2026-03-25T20:21:26.364Z" }, + { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290, upload-time = "2026-03-25T20:21:27.46Z" }, + { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141, upload-time = "2026-03-25T20:21:28.492Z" }, + { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847, upload-time = "2026-03-25T20:21:29.386Z" }, + { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088, upload-time = "2026-03-25T20:21:30.677Z" }, + { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866, upload-time = "2026-03-25T20:21:31.65Z" }, + { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887, upload-time = "2026-03-25T20:21:33.028Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704, upload-time = "2026-03-25T20:21:34.51Z" }, + { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628, upload-time = "2026-03-25T20:21:36.012Z" }, + { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180, upload-time = "2026-03-25T20:21:37.136Z" }, + { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674, upload-time = "2026-03-25T20:21:38.298Z" }, + { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976, upload-time = "2026-03-25T20:21:39.316Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755, upload-time = "2026-03-25T20:21:40.248Z" }, + { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265, upload-time = "2026-03-25T20:21:41.219Z" }, + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "tornado" +version = "6.5.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/06/61/53d562a57b28c08eda40b258c0f975e360541943ad7c7bef897a40caafda/tornado-6.5.10.tar.gz", hash = "sha256:a6b1ccd08c04b4a06fb5aeb381be99de5ad1e5375c1785e31d78c880feb57687", size = 537910, upload-time = "2026-09-15T13:47:48.73Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/5b/ff5fc58fa2427c30dea74c90053f4fc5eda1e7f3833ed3ecc7147fe2b311/tornado-6.5.10-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:9261783640e23258694a9ff0795df430a5a7b0a651d3dd53dd0969ad6be16da7", size = 465883, upload-time = "2026-09-15T13:47:35.463Z" }, + { url = "https://files.pythonhosted.org/packages/ad/f5/cd7be26c34a3315532f3aef5f092465da8f59c334dd439d3c14aaef16461/tornado-6.5.10-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:83e6cf438b106c6b3852d70960967bb1b70c87438050dca0981e4b9aa751a4c1", size = 464046, upload-time = "2026-09-15T13:47:37.178Z" }, + { url = "https://files.pythonhosted.org/packages/60/33/df6d7d04854a58619f8349a51e3edb138324130a7562b0bb21f115bb940f/tornado-6.5.10-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bdf942448169e5336451d0494d7e3d81cfa726d5aa312affdc4682dd62a62f6d", size = 467096, upload-time = "2026-09-15T13:47:38.559Z" }, + { url = "https://files.pythonhosted.org/packages/29/17/cc35dff68272d685cffd8600ffafbd8067e7d05e7348d9f80caddffbbd5f/tornado-6.5.10-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69acca6501eed74582b76dbbceee2a91613f54728e3e418346000d7103101676", size = 468067, upload-time = "2026-09-15T13:47:40.085Z" }, + { url = "https://files.pythonhosted.org/packages/c3/01/6e5349b4e1a53a4b4972a6716785e1fe7407f312063c3972690af8ff301b/tornado-6.5.10-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:66aaa3f57d30c6e6becee83ff28055d5930ac724214bde99393eefda83d5e015", size = 467901, upload-time = "2026-09-15T13:47:41.576Z" }, + { url = "https://files.pythonhosted.org/packages/28/5e/b4facf94370dba006819c8d304376f8b9fbec6b935b5e51bf45823a9790b/tornado-6.5.10-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4bd192b959f9128fb99b8898148070ba4574c9589b78bce42d1851131fe85828", size = 467308, upload-time = "2026-09-15T13:47:43.145Z" }, + { url = "https://files.pythonhosted.org/packages/56/ae/047938e828cafc8eca4c908fafb6588fee944e3af39a0af9d7b602499ae5/tornado-6.5.10-cp39-abi3-win32.whl", hash = "sha256:302eb1e0e3e159314eb591920529fdea80acca92df5510a2cec5bbd4f099ec72", size = 468387, upload-time = "2026-09-15T13:47:44.556Z" }, + { url = "https://files.pythonhosted.org/packages/d8/d4/5901517f05affd752490f6a654ba31b7474664e8dd80bd045a00c220bd88/tornado-6.5.10-cp39-abi3-win_amd64.whl", hash = "sha256:37ae8f150cecfdbf747fc4e12f5e9a97ecd8cf1d4cdb3f119e2de84b11196918", size = 468828, upload-time = "2026-09-15T13:47:45.961Z" }, + { url = "https://files.pythonhosted.org/packages/f3/1a/fd497f3a7f7b74bb04f4b94536b5c9f80742b5d50501fd27977652ddec16/tornado-6.5.10-cp39-abi3-win_arm64.whl", hash = "sha256:ce045d3c298fddd30e89a2777f97039d1b641eb9518ac7b26a4721903539c694", size = 467847, upload-time = "2026-09-15T13:47:47.283Z" }, +] + +[[package]] +name = "traitlets" +version = "5.16.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/2e/a7fbfe268c8a3b32546930c0297c101d65a4a14c304ad5790a9f478f0e4e/traitlets-5.16.1.tar.gz", hash = "sha256:ed900c2b631aa3a112811139fa97b8d2c3bad5e989656bba4b7e52c7852c18c1", size = 166137, upload-time = "2026-08-03T08:32:36.848Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ad/66/0d785f0bc5e4315a96c989bb476d0fc07ea4f85132550c7b156ca2035d52/traitlets-5.16.1-py3-none-any.whl", hash = "sha256:f775618166caa0396c8e337099240f2bd3e5e917d203b2e6fbe21a58d3cb1f6b", size = 86211, upload-time = "2026-08-03T08:32:34.48Z" }, +] + +[[package]] +name = "ty" +version = "0.0.81" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/61/b7/c9d736f48585f5a711ea47bb97a353d3771834f89481d747ea9687b74fa9/ty-0.0.81.tar.gz", hash = "sha256:ef721aa649bf41d665ba86e1ea726fd3feab6800e2c4887a062a704baf304ca8", size = 7225871, upload-time = "2026-09-15T02:05:29.536Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/70/649a5ec8fd6cc9dfa731c905523b19e677ad36dd9dcc4fcadfed8235507f/ty-0.0.81-py3-none-linux_armv6l.whl", hash = "sha256:8e9e3dd6edb1462633ddba2bf337d1c05023a5a13c2f315e445565c7ad43d247", size = 13679646, upload-time = "2026-09-15T02:04:51.436Z" }, + { url = "https://files.pythonhosted.org/packages/b5/d0/3769b760918c3dde1bbaeee87422cd442fc550baadb5c8621e479b363282/ty-0.0.81-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:649c350873e4b3e937d856512ee57b8a345d80079cbead73a5308c2cdafe594c", size = 13211367, upload-time = "2026-09-15T02:04:54.18Z" }, + { url = "https://files.pythonhosted.org/packages/f8/5f/b8fe3ab7eee87bbf1f5ff1b65c55526a3f31a9604630bc9e7d84199bbac5/ty-0.0.81-py3-none-macosx_11_0_arm64.whl", hash = "sha256:480c78706ba78239f901d68cf1ba53e98b84aa51e19b9241daa0fb62fdecd2e2", size = 13084312, upload-time = "2026-09-15T02:04:56.133Z" }, + { url = "https://files.pythonhosted.org/packages/7f/d8/ce22278014f14ae8205d2f9622696d39c623a0c9e80056c258bb89bb8322/ty-0.0.81-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cdbfa4b634b1d21542eedc11e424dedcc4871c2128d0d46b55b0089d3220492", size = 13127965, upload-time = "2026-09-15T02:04:58.306Z" }, + { url = "https://files.pythonhosted.org/packages/82/d0/4e75c61f6a241a0804f25117af4f91a5aaa4a48408b57f8d4c34d8a3d91e/ty-0.0.81-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f7a34743a21669d4f3d5fda98c36189cb4d9dceee1415a8a42d7426d55995db", size = 13432523, upload-time = "2026-09-15T02:05:00.471Z" }, + { url = "https://files.pythonhosted.org/packages/0b/02/e0b6b783418515c8ba40c13d5e333da9e0576a7a69582fc2b5831bb7d913/ty-0.0.81-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:742eab849947bc10b4c09810d37bd743afe9502e114b7bcfd6389f0ae3f425aa", size = 14211082, upload-time = "2026-09-15T02:05:02.455Z" }, + { url = "https://files.pythonhosted.org/packages/6b/af/85cb68d13ff617f2b213212d674e1266b933f2d051b63a1e5116e8ca0bfc/ty-0.0.81-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b4cef395eee7007449aa3fc3fc8dc6bc58fe7a8956d56db078569061741bf52", size = 14692204, upload-time = "2026-09-15T02:05:04.705Z" }, + { url = "https://files.pythonhosted.org/packages/24/c6/791891f3fa8fec91e9ec3e8c9d6774ab903297defe847a3e5d7e047360ad/ty-0.0.81-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80cf8c34973a1da2ec2a043efcba8f4c0a984d45210957a8ddd2c16f2b8f8e85", size = 14371010, upload-time = "2026-09-15T02:05:06.63Z" }, + { url = "https://files.pythonhosted.org/packages/c7/b2/c9fba5b4ed7f63f26e83432fa2062ca04606b61dce7bbacc1238232af649/ty-0.0.81-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f37a8f66c444eea29f17adfe0664f42062520773f18031fd4913f28eb56d2966", size = 13758537, upload-time = "2026-09-15T02:05:08.722Z" }, + { url = "https://files.pythonhosted.org/packages/77/e6/09c41e96bbcbe53dd18c9a1a6dbd2e456b0d03b94440a4bd9bab55a4e19a/ty-0.0.81-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:e8134cc03e84a27f409877b9b62053fd4aaac9c3ce0ce0fdace8b5ed58d78e04", size = 14280789, upload-time = "2026-09-15T02:05:10.719Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d1/87eb8e01fb17602cde5911cbadb9b11141a04f728dbda0a2a00243f337ca/ty-0.0.81-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:fb6f269c5f14a07047e05cbf3d06dd9a64a048050f736afcf744a180a272f034", size = 13169638, upload-time = "2026-09-15T02:05:12.806Z" }, + { url = "https://files.pythonhosted.org/packages/94/3c/137ceb792858f408c48f20a066d12ee76108e5f28a13242720879c024172/ty-0.0.81-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:38355a5e6294ebd3cee616ed581d051963d61b293a1b3351c248747f73a45b74", size = 13449856, upload-time = "2026-09-15T02:05:15.505Z" }, + { url = "https://files.pythonhosted.org/packages/fe/0a/4a9b31fadfc80a2141f3862316eb31944843e01bc1f6533794291cce767e/ty-0.0.81-py3-none-musllinux_1_2_i686.whl", hash = "sha256:59a35e128a9831423aee19db804aa8a1358ee3ce615b3fc0dec20d40bfd0d733", size = 13675303, upload-time = "2026-09-15T02:05:17.537Z" }, + { url = "https://files.pythonhosted.org/packages/e3/16/dbcd2c10ab80b015a227110a4ec75314468b6720d800261098521df4eee9/ty-0.0.81-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:f0f4219fbc068ea3414fa804c6bd57ef4229a11884ab9ca71cd8308072520aad", size = 14050298, upload-time = "2026-09-15T02:05:20.424Z" }, + { url = "https://files.pythonhosted.org/packages/95/ba/a70ced0c0c078ff09a3a80224d045c4267d07811dbaf125c749af5f72606/ty-0.0.81-py3-none-win32.whl", hash = "sha256:82ff952e64ba4c4da1c0c89723e326c768ae4f9ff20624dee04a51c3f4e4b96c", size = 12866650, upload-time = "2026-09-15T02:05:22.824Z" }, + { url = "https://files.pythonhosted.org/packages/3f/51/4b79453df93dfb9edecb1bd6cb04e772277d8c7260693165358a033b6ed1/ty-0.0.81-py3-none-win_amd64.whl", hash = "sha256:ef82788744da0b7f2a598e4e9776f9c5998df4eef7e2750ae3a5537e7c734b69", size = 13572976, upload-time = "2026-09-15T02:05:24.907Z" }, + { url = "https://files.pythonhosted.org/packages/0a/56/09594d55a0c49543eeac149c0dbc80b9b04409cc26ca48f1c1a9595c0916/ty-0.0.81-py3-none-win_arm64.whl", hash = "sha256:bdb1563990c5d3abfe5a09e7512733f302773ede6a5d3e4e5c6ad46393d8df4d", size = 13364408, upload-time = "2026-09-15T02:05:27.247Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] + +[[package]] +name = "tzdata" +version = "2026.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/31/3d74fa778a63b98b7374323befcc0be5ab3bd94afd4096a0124e7379152c/tzdata-2026.4.tar.gz", hash = "sha256:f1b8bd365d8d210c55353f4d7f8d6d8561c0ba50d704b700d195a9424bba0d79", size = 199350, upload-time = "2026-09-12T12:56:03.251Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/bc/8737e8d54cf51106118039b83f485a4783112fab49ea9d044b234978a46e/tzdata-2026.4-py2.py3-none-any.whl", hash = "sha256:c2169a8b0a7a5e9674da5a135ccdfb2b3e671b333ed9fed17b41f73c34476e81", size = 347494, upload-time = "2026-09-12T12:56:01.67Z" }, +] + +[[package]] +name = "urllib3" +version = "2.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/05/b17359e1cefb4f909b5e40b1b90a496d987258916dbbf88e842c729f510e/urllib3-2.8.0.tar.gz", hash = "sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63", size = 458972, upload-time = "2026-09-15T19:29:36.253Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/9d/c4e665119135114480843e7ab388fa94d8480650450e6f8e26b70d323a4c/urllib3-2.8.0-py3-none-any.whl", hash = "sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3", size = 135717, upload-time = "2026-09-15T19:29:34.577Z" }, +] + +[[package]] +name = "virtualenv" +version = "21.7.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, + { name = "python-discovery" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/45/9d/5acd348310e0803c658c8cf7c4d928e2d22fc4f79c29098b651cd3edfdba/virtualenv-21.7.10.tar.gz", hash = "sha256:a7bf10f37ecc36f1942d6e469d6b59f5fe308f60ac711f66f51ef3bd8cb2c9aa", size = 5350247, upload-time = "2026-09-15T23:36:05.739Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/7c/b75957b57ef372d84628b1099c4a530b3c361878cc6c54a8dfc5071d371a/virtualenv-21.7.10-py3-none-any.whl", hash = "sha256:d7ac9669ba19e675ffadbb97fe8e887ef92fb1743fe9a0032be62b947657327a", size = 5324900, upload-time = "2026-09-15T23:36:03.751Z" }, +] + +[[package]] +name = "wcwidth" +version = "0.8.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/36/57/ed58088fafdf4c55a0ad6bde846502567645424d7ebf325230b9237f4085/wcwidth-0.8.3.tar.gz", hash = "sha256:d128512515fbf4612e0ff21fd6380399210318b7b54a9af59dff8454cf9730eb", size = 1458450, upload-time = "2026-08-28T18:10:06.875Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c4/0e/57f6bb3024a597b2e8ec4aee710ffe62ddc95af2e2bb1ee7a7abdc22c68c/wcwidth-0.8.3-py3-none-any.whl", hash = "sha256:d5b73dba6158a595ec9370350e7f2637bcac8d6c5e4fde34f30fcffb6103a5e4", size = 331669, upload-time = "2026-08-28T18:10:04.909Z" }, +] + +[[package]] +name = "webencodings" +version = "0.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d5/a0/8fd707bcb776a7be556bad06a2ea5fb9bd519df78ef8e26f70ccf0f38bff/webencodings-0.6.1.tar.gz", hash = "sha256:565f9ad031c702dae404e27a099e3e09186a3ab1b9520f06d215502b651fd910", size = 15001, upload-time = "2026-08-15T14:22:57.549Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/c6/040cbc72480d789a5f40d63fb484d3106554c4dfa2d2b70ad5022057750f/webencodings-0.6.1-py3-none-any.whl", hash = "sha256:7fab6269c8bf237c657876b52058ccb182e861518d1c695c1a9aaa8c1c105d5b", size = 8745, upload-time = "2026-08-15T14:22:56.31Z" }, +] From a3def54a44accf5e622def07a453947d3aa36eb8 Mon Sep 17 00:00:00 2001 From: gsv Date: Wed, 16 Sep 2026 16:53:21 +0300 Subject: [PATCH 007/277] feat(37-S3): adopt ruff as the lint/format gate and bring the codebase in line Add [tool.ruff] config (target py311; rules E, F, W, I) with three justified per-file ignores: F403/F405 in __init__.py (star imports are the package's public-API re-export pattern and ruff cannot track names through them), E402 in docs/conf.py (Sphinx conf computes settings before importing extensions) and E402 in tests/utils/conftest.py (the sys.path insertion for the utils scripts must precede their imports). Run the one-time pass: ruff check --fix (import sorting, unused imports) and ruff format (37 files). Manual fixes: wrap 35 over-long docstring/comment/ f-string lines; rename ambiguous variable l -> label in a test; move the utils-sibling imports above the first module-level constant in utils/convert_old_to_new.py instead of ignoring E402. Two doctest adjustments were required, not suppressions: - cfpq_data/__init__.py no longer carries redundant bare submodule imports; one of them (import cfpq_data.config) had the side effect of exporting the name cfpq_data itself through 'from cfpq_data import *', which four doctests relied on. Those doctests now use the bare names the star import already provides. - The c_alias_grammar doctest printed a >88-char single-line repr; it now uses print() with +NORMALIZE_WHITESPACE so the grammar text is shown one production per line (the grammar text has trailing spaces that the trailing-whitespace hook would otherwise strip from the expected output). Verified: ruff check and ruff format --check are clean; full suite green (342 passed, doctests included). --- CHANGELOG.md | 3 ++ cfpq_data/__init__.py | 15 +++------ cfpq_data/dataset/data.py | 15 +++++---- cfpq_data/dataset/reachable_pairs.py | 1 + cfpq_data/grammars/converters/cfg.py | 6 ++-- cfpq_data/grammars/converters/cnf.py | 10 +++--- .../grammars/generators/c_alias_grammar.py | 25 +++++++++++---- cfpq_data/grammars/generators/dyck_grammar.py | 10 ++++-- .../generators/java_points_to_grammar.py | 17 +++++----- .../generators/nested_parentheses_grammar.py | 11 ++++--- cfpq_data/grammars/readwrite/__init__.py | 2 +- cfpq_data/grammars/readwrite/cfg.py | 3 +- cfpq_data/grammars/readwrite/cnf.py | 3 +- cfpq_data/grammars/readwrite/cnf_template.py | 1 + cfpq_data/grammars/readwrite/regex.py | 1 + cfpq_data/grammars/readwrite/rsa.py | 18 +++++++---- cfpq_data/grammars/utils/change_terminals.py | 10 +++--- .../generators/fast_labeled_binomial_graph.py | 3 +- .../labeled_barabasi_albert_graph.py | 7 +++-- .../generators/labeled_binomial_graph.py | 3 +- .../graphs/generators/labeled_cycle_graph.py | 3 +- .../generators/labeled_scale_free_graph.py | 3 +- .../generators/labeled_two_cycles_graph.py | 3 +- cfpq_data/graphs/readwrite/__init__.py | 4 +-- cfpq_data/graphs/readwrite/csv.py | 1 + cfpq_data/graphs/readwrite/mtx.py | 1 + cfpq_data/graphs/readwrite/rdf.py | 1 + cfpq_data/graphs/readwrite/txt.py | 3 +- cfpq_data/graphs/utils/__init__.py | 4 +-- cfpq_data/graphs/utils/add_reverse_edges.py | 7 +++-- cfpq_data/graphs/utils/change_edges.py | 1 + cfpq_data/graphs/utils/edges_statistics.py | 9 +++--- cfpq_data/graphs/utils/filter_edges.py | 5 ++- .../graphs/utils/multiple_source_utils.py | 31 ++++++++++++------- cfpq_data/graphs/utils/nodes_to_integers.py | 1 + pyproject.toml | 11 +++++++ tests/dataset/test_data.py | 2 +- .../generators/test_c_alias_grammar.py | 8 +++-- tests/grammars/readwrite/test_cnf_template.py | 17 ++-------- .../grammars/readwrite/test_rsa_readwrite.py | 3 -- tests/graphs/readwrite/test_mtx.py | 2 -- tests/graphs/readwrite/test_txt.py | 3 +- .../utils/test_multiple_source_utils.py | 4 +-- tests/utils/test_bump_version.py | 5 +-- tests/utils/test_convert_old_to_new.py | 22 +++++-------- tests/utils/test_migrate_gdrive_to_s3.py | 5 ++- tests/utils/test_upload_to_s3.py | 1 - utils/convert_old_to_new.py | 27 ++++++++-------- utils/migrate_gdrive_to_s3.py | 10 +++--- 49 files changed, 200 insertions(+), 161 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c88f681..3769c806 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The publish workflow now runs on every pull request targeting `master`: it builds the sdist and wheel and publishes them to TestPyPI (`skip-existing`), validating packaging before a release tag is cut. +- Ruff as the linting and formatting gate (rules `E`, `F`, `W`, `I` plus + `ruff format`), replacing black; the codebase was brought in line in a + one-time pass. ### Changed diff --git a/cfpq_data/__init__.py b/cfpq_data/__init__.py index e3b23b8a..353e49a0 100644 --- a/cfpq_data/__init__.py +++ b/cfpq_data/__init__.py @@ -7,21 +7,14 @@ experimental analysis of context-free path querying algorithms """ -import cfpq_data.config -from cfpq_data.config import * - -__version__ = VERSION +import logging -import cfpq_data.dataset +from cfpq_data.config import * from cfpq_data.dataset import * - -import cfpq_data.graphs -from cfpq_data.graphs import * - -import cfpq_data.grammars from cfpq_data.grammars import * +from cfpq_data.graphs import * -import logging +__version__ = VERSION logging.basicConfig( level=logging.INFO, diff --git a/cfpq_data/dataset/data.py b/cfpq_data/dataset/data.py index f4ae661d..3ef647d1 100644 --- a/cfpq_data/dataset/data.py +++ b/cfpq_data/dataset/data.py @@ -1,15 +1,15 @@ """Download graph data from dataset.""" + import logging import os import pathlib import shutil import tempfile +from typing import Union import requests -from typing import Union - -from cfpq_data.config import DATA, GRAPHS_DIR, GRAMMARS_DIR, BENCHMARKS_DIR, VERSION +from cfpq_data.config import BENCHMARKS_DIR, GRAMMARS_DIR, GRAPHS_DIR, VERSION __all__ = [ "DATASET_KEY_PREFIX", @@ -247,7 +247,8 @@ def download_grammars( The name of the grammar template from the dataset. graph_name : Union[str, None] - The name of the specified graph from the dataset or None for downloading example grammars. + The name of the specified graph from the dataset or None for + downloading example grammars. Examples -------- @@ -257,7 +258,8 @@ def download_grammars( Returns ------- path : Union[Path, None] - Path to the directory with grammars data or None if there is no such grammars in dataset. + Path to the directory with grammars data or None if there is no such + grammars in dataset. """ if template not in GRAMMAR_TEMPLATES: raise FileNotFoundError(f"No grammar {template=} found") @@ -296,7 +298,8 @@ def download_grammars( shutil.unpack_archive(grammar_archive, GRAMMARS_DIR) logging.info( - f"Unzip grammars with {template=} for graph with {graph_name=} to directory {grammars=}" + f"Unzip grammars with {template=} for graph with {graph_name=} " + f"to directory {grammars=}" ) os.remove(grammar_archive) diff --git a/cfpq_data/dataset/reachable_pairs.py b/cfpq_data/dataset/reachable_pairs.py index 77ff6941..c9ae6f46 100644 --- a/cfpq_data/dataset/reachable_pairs.py +++ b/cfpq_data/dataset/reachable_pairs.py @@ -1,4 +1,5 @@ """Reference reachable-pair counts for graph x grammar pairs.""" + import csv import pathlib from typing import Optional diff --git a/cfpq_data/grammars/converters/cfg.py b/cfpq_data/grammars/converters/cfg.py index 9e2cfe49..08597abc 100644 --- a/cfpq_data/grammars/converters/cfg.py +++ b/cfpq_data/grammars/converters/cfg.py @@ -1,8 +1,9 @@ """Create a context-free grammar from different formats.""" + import logging import re -from pyformlang.cfg import CFG, Variable, Production, Terminal +from pyformlang.cfg import CFG, Production, Terminal, Variable from pyformlang.regular_expression import Regex from pyformlang.rsa import RecursiveAutomaton as RSA @@ -107,7 +108,8 @@ def cfg_from_rsa(rsa: RSA) -> CFG: References ---------- .. [1] https://en.wikipedia.org/wiki/Context-free_grammar#Formal_definitions - .. [2] Alur R., Etessami K., Yannakakis M. (2001) Analysis of Recursive State Machines. + .. [2] Alur R., Etessami K., Yannakakis M. (2001) Analysis of Recursive + State Machines. In: Berry G., Comon H., Finkel A. (eds) Computer Aided Verification. CAV 2001. Lecture Notes in Computer Science, vol 2102. Springer, Berlin, Heidelberg. https://doi.org/10.1007/3-540-44585-4_18 diff --git a/cfpq_data/grammars/converters/cnf.py b/cfpq_data/grammars/converters/cnf.py index 62803f70..48af5d97 100644 --- a/cfpq_data/grammars/converters/cnf.py +++ b/cfpq_data/grammars/converters/cnf.py @@ -1,11 +1,12 @@ """Create a context-free grammar in Chomsky normal form from different formats.""" + import logging from pyformlang.cfg import CFG, Epsilon from pyformlang.regular_expression import Regex from pyformlang.rsa import RecursiveAutomaton as RSA -from cfpq_data.grammars.converters.cfg import cfg_from_rsa, cfg_from_regex +from cfpq_data.grammars.converters.cfg import cfg_from_regex, cfg_from_rsa __all__ = [ "cnf_from_cfg", @@ -27,7 +28,7 @@ def cnf_from_cfg(cfg: CFG) -> CFG: -------- >>> from cfpq_data import * >>> gr = cfg_from_text("S -> a b") - >>> cnf = cfpq_data.cnf_from_cfg(gr) + >>> cnf = cnf_from_cfg(gr) >>> cfg_to_text(cnf) 'S -> a#CNF# b#CNF#\\na#CNF# -> a\\nb#CNF# -> b' @@ -74,7 +75,7 @@ def cnf_from_regex(regex: Regex) -> CFG: -------- >>> from cfpq_data import * >>> expr = regex_from_text("a*") - >>> cnf = cfpq_data.cnf_from_regex(expr) + >>> cnf = cnf_from_regex(expr) >>> cfg_to_text(cnf) 'S -> \\nS -> S S\\nS -> a' @@ -121,7 +122,8 @@ def cnf_from_rsa(rsa: RSA) -> CFG: References ---------- .. [1] https://en.wikipedia.org/wiki/Chomsky_normal_form - .. [2] Alur R., Etessami K., Yannakakis M. (2001) Analysis of Recursive State Machines. + .. [2] Alur R., Etessami K., Yannakakis M. (2001) Analysis of Recursive + State Machines. In: Berry G., Comon H., Finkel A. (eds) Computer Aided Verification. CAV 2001. Lecture Notes in Computer Science, vol 2102. Springer, Berlin, Heidelberg. https://doi.org/10.1007/3-540-44585-4_18 diff --git a/cfpq_data/grammars/generators/c_alias_grammar.py b/cfpq_data/grammars/generators/c_alias_grammar.py index 5e1451fd..9d06daa4 100644 --- a/cfpq_data/grammars/generators/c_alias_grammar.py +++ b/cfpq_data/grammars/generators/c_alias_grammar.py @@ -1,6 +1,9 @@ -"""Returns a C Alias grammar that generates a language for the flow-insensitive alias analysis of C programs.""" +"""Returns a C Alias grammar that generates a language for the +flow-insensitive alias analysis of C programs.""" + import logging from typing import Tuple + from pyformlang.cfg import CFG, Variable import cfpq_data @@ -14,15 +17,18 @@ def c_alias_grammar( dereference_labels: Tuple[str, str] = ("d", "d_r"), start_symbol: Variable = Variable("S"), ) -> CFG: - """Returns a C Alias grammar that generates a language for the flow-insensitive alias analysis of C programs [1]_. + """Returns a C Alias grammar that generates a language for the + flow-insensitive alias analysis of C programs [1]_. Parameters ---------- assigment_labels : Tuple[str, str] - Pair $(a, a_r)$ where label $a$ represents the assignment operation and $a_r$ is reverse to it. + Pair $(a, a_r)$ where label $a$ represents the assignment operation + and $a_r$ is reverse to it. dereference_labels : Tuple[str, str] - Pair $(d, d_r)$ where label $d$ represents pointer dereference relation and $d_r$ is reverse to it. + Pair $(d, d_r)$ where label $d$ represents pointer dereference + relation and $d_r$ is reverse to it. start_symbol : Variable Start symbol of the grammar. @@ -31,8 +37,15 @@ def c_alias_grammar( -------- >>> from cfpq_data import * >>> cfg = c_alias_grammar() - >>> cfg_to_text(cfg) - 'S -> d_r V d\\nV -> V1 V2 V3\\nV1 -> \\nV1 -> V2 a_r V1\\nV2 -> \\nV2 -> S\\nV3 -> \\nV3 -> a V2 V3' + >>> print(cfg_to_text(cfg)) # doctest: +NORMALIZE_WHITESPACE + S -> d_r V d + V -> V1 V2 V3 + V1 -> + V1 -> V2 a_r V1 + V2 -> + V2 -> S + V3 -> + V3 -> a V2 V3 Returns ------- diff --git a/cfpq_data/grammars/generators/dyck_grammar.py b/cfpq_data/grammars/generators/dyck_grammar.py index e6b7eca4..df2f6ea4 100644 --- a/cfpq_data/grammars/generators/dyck_grammar.py +++ b/cfpq_data/grammars/generators/dyck_grammar.py @@ -1,7 +1,10 @@ -"""Returns a Dyck grammar that generates a Dyck language of the balanced strings with parentheses of different types.""" +"""Returns a Dyck grammar that generates a Dyck language of the balanced +strings with parentheses of different types.""" + import logging from typing import List, Tuple -from pyformlang.cfg import CFG, Production, Variable, Terminal + +from pyformlang.cfg import CFG, Production, Terminal, Variable __all__ = ["dyck_grammar"] @@ -12,7 +15,8 @@ def dyck_grammar( eps: bool = True, start_symbol: Variable = Variable("S"), ) -> CFG: - """Returns a Dyck grammar that generates a Dyck language [1]_ of the balanced strings with parentheses of given types. + """Returns a Dyck grammar that generates a Dyck language [1]_ of the + balanced strings with parentheses of given types. Parameters ---------- diff --git a/cfpq_data/grammars/generators/java_points_to_grammar.py b/cfpq_data/grammars/generators/java_points_to_grammar.py index 48d3ce78..c2791a00 100644 --- a/cfpq_data/grammars/generators/java_points_to_grammar.py +++ b/cfpq_data/grammars/generators/java_points_to_grammar.py @@ -1,10 +1,12 @@ -"""Returns a Java Points-to grammar that generates a language for the field-sensitive analysis of Java programs.""" +"""Returns a Java Points-to grammar that generates a language for the +field-sensitive analysis of Java programs.""" + import logging +import re from typing import List -from pyformlang.cfg import CFG, Production, Variable, Terminal import networkx as nx -import re +from pyformlang.cfg import CFG, Production, Terminal, Variable __all__ = ["java_points_to_grammar", "java_points_to_grammar_from_graph"] @@ -14,8 +16,8 @@ def java_points_to_grammar( *, start_symbol: Variable = Variable("S"), ) -> CFG: - """Returns a Java Points-to grammar that generates a language for the field-sensitive analysis of Java programs [1]_ - with given fields labels. + """Returns a Java Points-to grammar that generates a language for the + field-sensitive analysis of Java programs [1]_ with given fields labels. Parameters ---------- @@ -115,8 +117,9 @@ def java_points_to_grammar_from_graph( *, start_symbol: Variable = Variable("S"), ) -> CFG: - """Returns a Java Points-to grammar that generates a language for the field-sensitive analysis of Java programs [1]_ - with fields corresponding to the load and store edge labels of the given graph. + """Returns a Java Points-to grammar that generates a language for the + field-sensitive analysis of Java programs [1]_ with fields corresponding + to the load and store edge labels of the given graph. Parameters ---------- diff --git a/cfpq_data/grammars/generators/nested_parentheses_grammar.py b/cfpq_data/grammars/generators/nested_parentheses_grammar.py index d0d2fe1d..8f1c08e8 100644 --- a/cfpq_data/grammars/generators/nested_parentheses_grammar.py +++ b/cfpq_data/grammars/generators/nested_parentheses_grammar.py @@ -1,8 +1,10 @@ -"""Returns a Nested Parentheses grammar that generates a language of the strings with nested parentheses of different -types. """ +"""Returns a Nested Parentheses grammar that generates a language of the +strings with nested parentheses of different types.""" + import logging from typing import List, Tuple -from pyformlang.cfg import CFG, Production, Variable, Terminal + +from pyformlang.cfg import CFG, Production, Terminal, Variable __all__ = ["nested_parentheses_grammar"] @@ -13,7 +15,8 @@ def nested_parentheses_grammar( eps: bool = True, start_symbol: Variable = Variable("S"), ) -> CFG: - """Returns a Nested Parentheses grammar that generates a language of the strings with nested parentheses of given types. + """Returns a Nested Parentheses grammar that generates a language of the + strings with nested parentheses of given types. Parameters ---------- diff --git a/cfpq_data/grammars/readwrite/__init__.py b/cfpq_data/grammars/readwrite/__init__.py index 66dc58b1..3b2b471a 100644 --- a/cfpq_data/grammars/readwrite/__init__.py +++ b/cfpq_data/grammars/readwrite/__init__.py @@ -1,5 +1,5 @@ from cfpq_data.grammars.readwrite.cfg import * from cfpq_data.grammars.readwrite.cnf import * from cfpq_data.grammars.readwrite.cnf_template import * -from cfpq_data.grammars.readwrite.rsa import * from cfpq_data.grammars.readwrite.regex import * +from cfpq_data.grammars.readwrite.rsa import * diff --git a/cfpq_data/grammars/readwrite/cfg.py b/cfpq_data/grammars/readwrite/cfg.py index 0ed3cb86..a1bd5c7d 100644 --- a/cfpq_data/grammars/readwrite/cfg.py +++ b/cfpq_data/grammars/readwrite/cfg.py @@ -1,9 +1,10 @@ """Read (and write) a context-free grammar from (and to) different sources.""" + import logging import pathlib from typing import Union -from pyformlang.cfg import Variable, CFG +from pyformlang.cfg import CFG, Variable __all__ = [ "cfg_from_text", diff --git a/cfpq_data/grammars/readwrite/cnf.py b/cfpq_data/grammars/readwrite/cnf.py index d6f2af96..9a6b0d57 100644 --- a/cfpq_data/grammars/readwrite/cnf.py +++ b/cfpq_data/grammars/readwrite/cnf.py @@ -1,10 +1,11 @@ """Read (and write) a context-free grammar in Chomsky normal form from (and to) different sources.""" + import logging import pathlib from typing import Union -from pyformlang.cfg import Variable, CFG +from pyformlang.cfg import CFG, Variable from cfpq_data.grammars.converters.cnf import cnf_from_cfg from cfpq_data.grammars.readwrite.cfg import cfg_from_text diff --git a/cfpq_data/grammars/readwrite/cnf_template.py b/cfpq_data/grammars/readwrite/cnf_template.py index 96729b42..bb560f1a 100644 --- a/cfpq_data/grammars/readwrite/cnf_template.py +++ b/cfpq_data/grammars/readwrite/cnf_template.py @@ -1,5 +1,6 @@ """Read (and write) grammar templates in the ``.cnf`` format of the new-format graph archives, and materialize them over a concrete graph.""" + import logging import pathlib from typing import List, Optional, Set, Tuple, Union diff --git a/cfpq_data/grammars/readwrite/regex.py b/cfpq_data/grammars/readwrite/regex.py index c3683863..e0e3b687 100644 --- a/cfpq_data/grammars/readwrite/regex.py +++ b/cfpq_data/grammars/readwrite/regex.py @@ -1,4 +1,5 @@ """Read (and write) a regular expression from (and to) different sources.""" + import logging import pathlib from typing import Union diff --git a/cfpq_data/grammars/readwrite/rsa.py b/cfpq_data/grammars/readwrite/rsa.py index 44474a43..1d570acd 100644 --- a/cfpq_data/grammars/readwrite/rsa.py +++ b/cfpq_data/grammars/readwrite/rsa.py @@ -1,13 +1,15 @@ """Read (and write) a Recursive State Automaton from (and to) different sources.""" + import logging import pathlib from typing import Union -from pyformlang.cfg import Epsilon, Variable, Production +from pyformlang.cfg import Epsilon from pyformlang.finite_automaton import Symbol from pyformlang.finite_automaton.finite_automaton import to_symbol from pyformlang.regular_expression import Regex -from pyformlang.rsa import Box, RecursiveAutomaton as RSA +from pyformlang.rsa import Box +from pyformlang.rsa import RecursiveAutomaton as RSA __all__ = [ "rsa_from_text", @@ -42,7 +44,8 @@ def rsa_from_text(text: str, *, start_symbol: Symbol = Symbol("S")) -> RSA: References ---------- - .. [1] Alur R., Etessami K., Yannakakis M. (2001) Analysis of Recursive State Machines. + .. [1] Alur R., Etessami K., Yannakakis M. (2001) Analysis of Recursive + State Machines. In: Berry G., Comon H., Finkel A. (eds) Computer Aided Verification. CAV 2001. Lecture Notes in Computer Science, vol 2102. Springer, Berlin, Heidelberg. https://doi.org/10.1007/3-540-44585-4_18 @@ -98,7 +101,8 @@ def rsa_to_text(rsa: RSA) -> str: References ---------- - .. [1] Alur R., Etessami K., Yannakakis M. (2001) Analysis of Recursive State Machines. + .. [1] Alur R., Etessami K., Yannakakis M. (2001) Analysis of Recursive + State Machines. In: Berry G., Comon H., Finkel A. (eds) Computer Aided Verification. CAV 2001. Lecture Notes in Computer Science, vol 2102. Springer, Berlin, Heidelberg. https://doi.org/10.1007/3-540-44585-4_18 @@ -150,7 +154,8 @@ def rsa_from_txt( References ---------- - .. [1] Alur R., Etessami K., Yannakakis M. (2001) Analysis of Recursive State Machines. + .. [1] Alur R., Etessami K., Yannakakis M. (2001) Analysis of Recursive + State Machines. In: Berry G., Comon H., Finkel A. (eds) Computer Aided Verification. CAV 2001. Lecture Notes in Computer Science, vol 2102. Springer, Berlin, Heidelberg. https://doi.org/10.1007/3-540-44585-4_18 @@ -191,7 +196,8 @@ def rsa_to_txt(rsa: RSA, path: Union[pathlib.Path, str]) -> pathlib.Path: References ---------- - .. [1] Alur R., Etessami K., Yannakakis M. (2001) Analysis of Recursive State Machines. + .. [1] Alur R., Etessami K., Yannakakis M. (2001) Analysis of Recursive + State Machines. In: Berry G., Comon H., Finkel A. (eds) Computer Aided Verification. CAV 2001. Lecture Notes in Computer Science, vol 2102. Springer, Berlin, Heidelberg. https://doi.org/10.1007/3-540-44585-4_18 diff --git a/cfpq_data/grammars/utils/change_terminals.py b/cfpq_data/grammars/utils/change_terminals.py index c9e5729c..235ae8ec 100644 --- a/cfpq_data/grammars/utils/change_terminals.py +++ b/cfpq_data/grammars/utils/change_terminals.py @@ -1,4 +1,5 @@ """Change terminals of a context-free grammar in different formats.""" + import logging import re from typing import Dict @@ -7,10 +8,10 @@ from pyformlang.regular_expression import Regex from pyformlang.rsa import RecursiveAutomaton as RSA -from cfpq_data.grammars.readwrite.cfg import cfg_to_text, cfg_from_text +from cfpq_data.grammars.readwrite.cfg import cfg_from_text, cfg_to_text from cfpq_data.grammars.readwrite.cnf import cnf_from_text -from cfpq_data.grammars.readwrite.regex import regex_to_text, regex_from_text -from cfpq_data.grammars.readwrite.rsa import rsa_to_text, rsa_from_text +from cfpq_data.grammars.readwrite.regex import regex_from_text, regex_to_text +from cfpq_data.grammars.readwrite.rsa import rsa_from_text, rsa_to_text __all__ = [ "change_terminals_in_cfg", @@ -161,7 +162,8 @@ def change_terminals_in_rsa(rsa: RSA, mapping: Dict[str, str]) -> RSA: References ---------- - .. [1] Alur R., Etessami K., Yannakakis M. (2001) Analysis of Recursive State Machines. + .. [1] Alur R., Etessami K., Yannakakis M. (2001) Analysis of Recursive + State Machines. In: Berry G., Comon H., Finkel A. (eds) Computer Aided Verification. CAV 2001. Lecture Notes in Computer Science, vol 2102. Springer, Berlin, Heidelberg. https://doi.org/10.1007/3-540-44585-4_18 diff --git a/cfpq_data/graphs/generators/fast_labeled_binomial_graph.py b/cfpq_data/graphs/generators/fast_labeled_binomial_graph.py index 61c5139f..b82162a3 100644 --- a/cfpq_data/graphs/generators/fast_labeled_binomial_graph.py +++ b/cfpq_data/graphs/generators/fast_labeled_binomial_graph.py @@ -1,8 +1,9 @@ """Returns a $G_{n,p}$ random graph, also known as an Erdős-Rényi graph or a binomial graph. With labeled edges.""" + import logging import random -from typing import Union, List, Callable +from typing import Callable, List, Union import networkx as nx diff --git a/cfpq_data/graphs/generators/labeled_barabasi_albert_graph.py b/cfpq_data/graphs/generators/labeled_barabasi_albert_graph.py index 77ff2ac6..5f05d6f6 100644 --- a/cfpq_data/graphs/generators/labeled_barabasi_albert_graph.py +++ b/cfpq_data/graphs/generators/labeled_barabasi_albert_graph.py @@ -4,9 +4,10 @@ A graph of ``n`` nodes is grown by attaching new nodes each with ``m`` edges that are preferentially attached to existing nodes with high degree. """ + import logging import random -from typing import List, Union, Callable +from typing import Callable, List, Union import networkx as nx @@ -21,8 +22,8 @@ def labeled_barabasi_albert_graph( choice: Callable[[List[str]], str] = random.choice, seed: Union[int, None] = None, ) -> nx.MultiDiGraph: - """Returns a random graph according to the Barabási–Albert preferential attachment model. - With labeled edges. + """Returns a random graph according to the Barabási–Albert + preferential attachment model. With labeled edges. A graph of ``n`` nodes is grown by attaching new nodes each with ``m`` edges that are preferentially attached to existing nodes with high degree. diff --git a/cfpq_data/graphs/generators/labeled_binomial_graph.py b/cfpq_data/graphs/generators/labeled_binomial_graph.py index 581c358b..14993263 100644 --- a/cfpq_data/graphs/generators/labeled_binomial_graph.py +++ b/cfpq_data/graphs/generators/labeled_binomial_graph.py @@ -1,9 +1,10 @@ """Returns a $G_{n,p}$ random graph, also known as an Erdős-Rényi graph or a binomial graph. With labeled edges. """ + import logging import random -from typing import Union, List, Callable +from typing import Callable, List, Union import networkx as nx diff --git a/cfpq_data/graphs/generators/labeled_cycle_graph.py b/cfpq_data/graphs/generators/labeled_cycle_graph.py index 3300b8d9..b525fbfd 100644 --- a/cfpq_data/graphs/generators/labeled_cycle_graph.py +++ b/cfpq_data/graphs/generators/labeled_cycle_graph.py @@ -2,8 +2,9 @@ $C_n$ is a path with its two end-nodes connected. """ + import logging -from typing import Union, Iterable, Any +from typing import Any, Iterable, Union import networkx as nx diff --git a/cfpq_data/graphs/generators/labeled_scale_free_graph.py b/cfpq_data/graphs/generators/labeled_scale_free_graph.py index 7caf5d0d..66a0be59 100644 --- a/cfpq_data/graphs/generators/labeled_scale_free_graph.py +++ b/cfpq_data/graphs/generators/labeled_scale_free_graph.py @@ -1,7 +1,8 @@ """Returns a scale-free directed graph. With labeled edges.""" + import logging import random -from typing import Union, Iterable, Callable +from typing import Callable, Iterable, Union import networkx as nx diff --git a/cfpq_data/graphs/generators/labeled_two_cycles_graph.py b/cfpq_data/graphs/generators/labeled_two_cycles_graph.py index 2b6a6ac0..9ab5ad5f 100644 --- a/cfpq_data/graphs/generators/labeled_two_cycles_graph.py +++ b/cfpq_data/graphs/generators/labeled_two_cycles_graph.py @@ -1,6 +1,7 @@ """Returns a graph with two cycles connected by one node. With labeled edges.""" + import logging -from typing import Union, Iterable, Any, Tuple +from typing import Any, Iterable, Tuple, Union import networkx as nx diff --git a/cfpq_data/graphs/readwrite/__init__.py b/cfpq_data/graphs/readwrite/__init__.py index ce5c36f7..829dd33b 100644 --- a/cfpq_data/graphs/readwrite/__init__.py +++ b/cfpq_data/graphs/readwrite/__init__.py @@ -1,4 +1,4 @@ -from cfpq_data.graphs.readwrite.rdf import * -from cfpq_data.graphs.readwrite.txt import * from cfpq_data.graphs.readwrite.csv import * from cfpq_data.graphs.readwrite.mtx import * +from cfpq_data.graphs.readwrite.rdf import * +from cfpq_data.graphs.readwrite.txt import * diff --git a/cfpq_data/graphs/readwrite/csv.py b/cfpq_data/graphs/readwrite/csv.py index 7c32161c..d8055ff6 100644 --- a/cfpq_data/graphs/readwrite/csv.py +++ b/cfpq_data/graphs/readwrite/csv.py @@ -1,4 +1,5 @@ """Read (and write) a graph from (and to) CSV file.""" + import logging import pathlib from typing import Union diff --git a/cfpq_data/graphs/readwrite/mtx.py b/cfpq_data/graphs/readwrite/mtx.py index 12fc4bed..72232fce 100644 --- a/cfpq_data/graphs/readwrite/mtx.py +++ b/cfpq_data/graphs/readwrite/mtx.py @@ -1,4 +1,5 @@ """Read (and write) a graph from (and to) a directory of MatrixMarket files.""" + import logging import pathlib from typing import Dict, List, Tuple, Union diff --git a/cfpq_data/graphs/readwrite/rdf.py b/cfpq_data/graphs/readwrite/rdf.py index eed2882c..bd3d84bf 100644 --- a/cfpq_data/graphs/readwrite/rdf.py +++ b/cfpq_data/graphs/readwrite/rdf.py @@ -1,4 +1,5 @@ """Read (and write) a graph from (and to) RDF file.""" + import logging import pathlib from typing import Union diff --git a/cfpq_data/graphs/readwrite/txt.py b/cfpq_data/graphs/readwrite/txt.py index c75f43a9..f2e5ee70 100644 --- a/cfpq_data/graphs/readwrite/txt.py +++ b/cfpq_data/graphs/readwrite/txt.py @@ -1,8 +1,9 @@ """Read (and write) a graph from (and to) TXT file.""" + import logging import pathlib import shlex -from typing import Union, Iterable, Iterator +from typing import Iterable, Iterator, Union import networkx as nx diff --git a/cfpq_data/graphs/utils/__init__.py b/cfpq_data/graphs/utils/__init__.py index 3e660a30..b61bebe1 100644 --- a/cfpq_data/graphs/utils/__init__.py +++ b/cfpq_data/graphs/utils/__init__.py @@ -1,6 +1,6 @@ from cfpq_data.graphs.utils.add_reverse_edges import * from cfpq_data.graphs.utils.change_edges import * -from cfpq_data.graphs.utils.filter_edges import * from cfpq_data.graphs.utils.edges_statistics import * -from cfpq_data.graphs.utils.nodes_to_integers import * +from cfpq_data.graphs.utils.filter_edges import * from cfpq_data.graphs.utils.multiple_source_utils import * +from cfpq_data.graphs.utils.nodes_to_integers import * diff --git a/cfpq_data/graphs/utils/add_reverse_edges.py b/cfpq_data/graphs/utils/add_reverse_edges.py index 8b0aac35..ece91f0e 100644 --- a/cfpq_data/graphs/utils/add_reverse_edges.py +++ b/cfpq_data/graphs/utils/add_reverse_edges.py @@ -1,4 +1,5 @@ """Returns a graph with added reverse edges.""" + import logging from typing import Any, Dict, Union @@ -25,12 +26,12 @@ def add_reverse_edges( Examples -------- >>> from cfpq_data import * - >>> g = labeled_cycle_graph(2) + >>> g = labeled_cycle_graph(1) >>> list(g.edges(data=True)) - [(0, 1, {'label': 'a'}), (1, 0, {'label': 'a'})] + [(0, 0, {'label': 'a'})] >>> new_g = add_reverse_edges(g) >>> list(new_g.edges(data=True)) - [(0, 1, {'label': 'a'}), (0, 1, {'label': 'a_r'}), (1, 0, {'label': 'a_r'}), (1, 0, {'label': 'a'})] + [(0, 0, {'label': 'a'}), (0, 0, {'label': 'a_r'})] Returns ------- diff --git a/cfpq_data/graphs/utils/change_edges.py b/cfpq_data/graphs/utils/change_edges.py index 89ca3ee4..df80e425 100644 --- a/cfpq_data/graphs/utils/change_edges.py +++ b/cfpq_data/graphs/utils/change_edges.py @@ -1,4 +1,5 @@ """Returns a graph with changed edges by specified edge labels mapping.""" + import logging from typing import Any, Dict diff --git a/cfpq_data/graphs/utils/edges_statistics.py b/cfpq_data/graphs/utils/edges_statistics.py index 8942f7d5..2171a165 100644 --- a/cfpq_data/graphs/utils/edges_statistics.py +++ b/cfpq_data/graphs/utils/edges_statistics.py @@ -1,7 +1,8 @@ """Returns statistics of graph edges.""" + import logging from collections import defaultdict -from typing import List, Any, DefaultDict +from typing import Any, DefaultDict, List import networkx as nx @@ -20,8 +21,6 @@ def get_labels_frequency(graph: nx.MultiDiGraph) -> DefaultDict[Any, int]: -------- >>> from cfpq_data import * >>> g = labeled_two_cycles_graph(1, 1, labels=("a", "b")) - >>> list(g.edges(data=True)) - [(1, 0, {'label': 'a'}), (0, 1, {'label': 'a'}), (0, 2, {'label': 'b'}), (2, 0, {'label': 'b'})] >>> labels_frequency = get_labels_frequency(g) >>> labels_frequency defaultdict(, {'a': 2, 'b': 2}) @@ -47,8 +46,8 @@ def get_sorted_labels( *, reverse: bool = False, ) -> List[Any]: - """Returns a list of edge labels sorted by the number of uses in the graph. The labels with equal number of uses are - sorted lexicographically. + """Returns a list of edge labels sorted by the number of uses in the + graph. The labels with equal number of uses are sorted lexicographically. Parameters ---------- diff --git a/cfpq_data/graphs/utils/filter_edges.py b/cfpq_data/graphs/utils/filter_edges.py index 1d01cb5a..b339191d 100644 --- a/cfpq_data/graphs/utils/filter_edges.py +++ b/cfpq_data/graphs/utils/filter_edges.py @@ -1,6 +1,7 @@ """Returns a graph with filtered edges.""" + import logging -from typing import Iterable, Any +from typing import Any, Iterable import networkx as nx @@ -22,8 +23,6 @@ def filter_edges(graph: nx.MultiDiGraph, labels: Iterable[Any]) -> nx.MultiDiGra -------- >>> from cfpq_data import * >>> g = labeled_two_cycles_graph(1, 1, labels=("a", "b")) - >>> list(g.edges(data=True)) - [(1, 0, {'label': 'a'}), (0, 1, {'label': 'a'}), (0, 2, {'label': 'b'}), (2, 0, {'label': 'b'})] >>> new_g = filter_edges(g, ["a"]) >>> list(new_g.edges(data=True)) [(1, 0, {'label': 'a'}), (0, 1, {'label': 'a'})] diff --git a/cfpq_data/graphs/utils/multiple_source_utils.py b/cfpq_data/graphs/utils/multiple_source_utils.py index d548067f..5d3880fb 100644 --- a/cfpq_data/graphs/utils/multiple_source_utils.py +++ b/cfpq_data/graphs/utils/multiple_source_utils.py @@ -1,7 +1,8 @@ """Utilities for the multiple-source query evaluation.""" -import random + import logging import pathlib +import random import shlex from typing import Set, Tuple, Union @@ -40,8 +41,8 @@ def generate_multiple_source( -------- >>> from cfpq_data import * >>> seed = 42 - >>> g = cfpq_data.labeled_two_cycles_graph(42, 29) - >>> source_vertices = cfpq_data.generate_multiple_source(g, 10, seed=seed) + >>> g = labeled_two_cycles_graph(42, 29) + >>> source_vertices = generate_multiple_source(g, 10, seed=seed) >>> source_vertices {32, 3, 4, 36, 12, 14, 15, 18, 54, 29} @@ -63,7 +64,8 @@ def generate_multiple_source( source_vertices = set(random.sample(list(graph.nodes), set_size)) logging.info( - f"Generate set of source vertices of {set_size} nodes for {graph=} for multiple-source evaluation" + f"Generate set of source vertices of {set_size} nodes for {graph=} " + f"for multiple-source evaluation" ) return source_vertices @@ -75,7 +77,8 @@ def generate_multiple_source_percent( *, seed: Union[int, None] = None, ) -> Set[int]: - """Returns a set of graph vertices with the given percent of vertices for multiple-source evaluation. + """Returns a set of graph vertices with the given percent of vertices + for multiple-source evaluation. Parameters ---------- @@ -91,11 +94,11 @@ def generate_multiple_source_percent( Examples -------- >>> from cfpq_data import * - >>> g = cfpq_data.labeled_two_cycles_graph(42, 29) + >>> g = labeled_two_cycles_graph(42, 29) >>> g.number_of_nodes() 72 >>> seed = 42 - >>> source_vertices = cfpq_data.generate_multiple_source_percent(g, 10.0, seed=seed) + >>> source_vertices = generate_multiple_source_percent(g, 10.0, seed=seed) >>> source_vertices {32, 4, 36, 14, 15, 18, 29} @@ -187,9 +190,10 @@ def multiple_source_to_txt( def multiple_source_result_from_txt( - path: Union[pathlib.Path, str] + path: Union[pathlib.Path, str], ) -> Set[Tuple[int, int]]: - """Returns a set with the result of multiple-source query evaluation loaded from a TXT file. + """Returns a set with the result of multiple-source query evaluation + loaded from a TXT file. Parameters ---------- @@ -229,7 +233,8 @@ def multiple_source_result_from_txt( def multiple_source_result_to_txt( reachable_pairs: Set[Tuple[int, int]], path: Union[pathlib.Path, str] ) -> pathlib.Path: - """Returns a path to the TXT file where the multiple-source query evaluation result will be saved. + """Returns a path to the TXT file where the multiple-source query + evaluation result will be saved. Parameters ---------- @@ -237,7 +242,8 @@ def multiple_source_result_to_txt( The multiple-source query evaluation result to save. path: Union[Path, str] - The path to the file where the multiple-source query evaluation result will be saved. + The path to the file where the multiple-source query evaluation + result will be saved. Examples -------- @@ -248,7 +254,8 @@ def multiple_source_result_to_txt( Returns ------- path : Path - Path to a TXT file where the multiple-source query evaluation result will be saved. + Path to a TXT file where the multiple-source query evaluation + result will be saved. """ with open(path, "w") as f: for u, v in reachable_pairs: diff --git a/cfpq_data/graphs/utils/nodes_to_integers.py b/cfpq_data/graphs/utils/nodes_to_integers.py index 77afcb34..5c2e7402 100644 --- a/cfpq_data/graphs/utils/nodes_to_integers.py +++ b/cfpq_data/graphs/utils/nodes_to_integers.py @@ -1,4 +1,5 @@ """Returns a graph with nodes converted to integers.""" + import logging import networkx as nx diff --git a/pyproject.toml b/pyproject.toml index e7b3fb8e..05152e33 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,6 +78,17 @@ include = [ "LICENSE-DATA.txt", ] +[tool.ruff] +target-version = "py311" + +[tool.ruff.lint] +select = ["E", "F", "W", "I"] + +[tool.ruff.lint.per-file-ignores] +"__init__.py" = ["F403", "F405"] +"docs/conf.py" = ["E402"] +"tests/utils/conftest.py" = ["E402"] + [tool.pytest.ini_options] addopts = "--doctest-modules -vv -s" testpaths = ["cfpq_data", "tests"] diff --git a/tests/dataset/test_data.py b/tests/dataset/test_data.py index 68ee97ea..3ef37283 100644 --- a/tests/dataset/test_data.py +++ b/tests/dataset/test_data.py @@ -42,7 +42,7 @@ def test_download_grammars_none(): @pytest.mark.parametrize("template,graph_name", [("dyck", None)]) def test_download_grammars_success(template, graph_name): - assert not cfpq_data.download_grammars(template, graph_name=graph_name) is None + assert cfpq_data.download_grammars(template, graph_name=graph_name) is not None def test_download_benchmark_rise(): diff --git a/tests/grammars/generators/test_c_alias_grammar.py b/tests/grammars/generators/test_c_alias_grammar.py index 92c31b33..6f4e26e0 100644 --- a/tests/grammars/generators/test_c_alias_grammar.py +++ b/tests/grammars/generators/test_c_alias_grammar.py @@ -4,14 +4,18 @@ cfg_1 = cfpq_data.c_alias_grammar() expected_cfg_1 = cfpq_data.cfg_from_text( - "S -> d_r V d\nV -> V1 V2 V3\nV1 -> \nV1 -> V2 a_r V1\nV2 -> \nV2 -> S\nV3 -> \nV3 -> a V2 V3" + "S -> d_r V d\nV -> V1 V2 V3\n" + "V1 -> \nV1 -> V2 a_r V1\nV2 -> \nV2 -> S\n" + "V3 -> \nV3 -> a V2 V3" ) cfg_2 = cfpq_data.c_alias_grammar( assigment_labels=("assign", "assign_r"), dereference_labels=("deref", "deref_r") ) expected_cfg_2 = cfpq_data.cfg_from_text( - "S -> deref_r V deref\nV -> V1 V2 V3\nV1 -> \nV1 -> V2 assign_r V1\nV2 -> \nV2 -> S\nV3 -> \nV3 -> assign V2 V3" + "S -> deref_r V deref\nV -> V1 V2 V3\n" + "V1 -> \nV1 -> V2 assign_r V1\nV2 -> \nV2 -> S\n" + "V3 -> \nV3 -> assign V2 V3" ) diff --git a/tests/grammars/readwrite/test_cnf_template.py b/tests/grammars/readwrite/test_cnf_template.py index 078f0ff8..0a92c577 100644 --- a/tests/grammars/readwrite/test_cnf_template.py +++ b/tests/grammars/readwrite/test_cnf_template.py @@ -152,9 +152,7 @@ def test_materialize_i_style(): def test_materialize_inert_symbols(): - template = ( - "S\tsubClassOf\tN1\n" "N1\tS\ttype\n" "S\ttype_r\ttype\n" "\n" "Count:\n" "S\n" - ) + template = "S\tsubClassOf\tN1\nN1\tS\ttype\nS\ttype_r\ttype\n\nCount:\nS\n" g = nx.MultiDiGraph() g.add_edge(0, 1, label="type") @@ -166,7 +164,7 @@ def test_materialize_inert_symbols(): def test_materialize_rejects_indexed_start_symbol(): - template = "load_i\tPTh\n" "PTh\talloc\n" "\n" "Count:\n" "load_i\n" + template = "load_i\tPTh\nPTh\talloc\n\nCount:\nload_i\n" with pytest.raises(ValueError, match="must not be indexed"): materialize(cnf_template_from_text(template), _java_graph(["0"])) @@ -197,16 +195,7 @@ def test_materialize_rejects_indexed_start_symbol(): "PT\n" ) -CSCVF_TEMPLATE = ( - "A\n" - "A\tA\tB\n" - "A\tA\ta\n" - "B\tcall_i\tAR_i\n" - "AR_i\tA\tret_i\n" - "\n" - "Count:\n" - "A\n" -) +CSCVF_TEMPLATE = "A\nA\tA\tB\nA\tA\ta\nB\tcall_i\tAR_i\nAR_i\tA\tret_i\n\nCount:\nA\n" FSCA_TEMPLATE = ( "M\tDV\td\n" diff --git a/tests/grammars/readwrite/test_rsa_readwrite.py b/tests/grammars/readwrite/test_rsa_readwrite.py index 3c6d7a48..7d8c5c34 100644 --- a/tests/grammars/readwrite/test_rsa_readwrite.py +++ b/tests/grammars/readwrite/test_rsa_readwrite.py @@ -1,6 +1,3 @@ -import os -import tempfile - import pytest import cfpq_data diff --git a/tests/graphs/readwrite/test_mtx.py b/tests/graphs/readwrite/test_mtx.py index 5a410ea7..58456440 100644 --- a/tests/graphs/readwrite/test_mtx.py +++ b/tests/graphs/readwrite/test_mtx.py @@ -1,5 +1,3 @@ -import pathlib - import networkx as nx import pytest diff --git a/tests/graphs/readwrite/test_txt.py b/tests/graphs/readwrite/test_txt.py index 9470f4a9..90575372 100644 --- a/tests/graphs/readwrite/test_txt.py +++ b/tests/graphs/readwrite/test_txt.py @@ -1,8 +1,7 @@ -from itertools import product import os import random +from itertools import product -import networkx as nx import pytest import cfpq_data diff --git a/tests/graphs/utils/test_multiple_source_utils.py b/tests/graphs/utils/test_multiple_source_utils.py index d9c6bacc..0475e2fa 100644 --- a/tests/graphs/utils/test_multiple_source_utils.py +++ b/tests/graphs/utils/test_multiple_source_utils.py @@ -1,8 +1,8 @@ -import pytest - import os import pathlib +import pytest + import cfpq_data seed = 42 diff --git a/tests/utils/test_bump_version.py b/tests/utils/test_bump_version.py index dae5f1be..02a98791 100644 --- a/tests/utils/test_bump_version.py +++ b/tests/utils/test_bump_version.py @@ -1,9 +1,6 @@ -import pathlib - -import pytest - import bump_version import check_version_sync +import pytest @pytest.fixture diff --git a/tests/utils/test_convert_old_to_new.py b/tests/utils/test_convert_old_to_new.py index 9566fbe4..2c50d32c 100644 --- a/tests/utils/test_convert_old_to_new.py +++ b/tests/utils/test_convert_old_to_new.py @@ -6,16 +6,14 @@ from collections import Counter import pytest -from pyformlang.cfg import CFG, Production, Terminal, Variable - from convert_old_to_new import ( + JAVA_START, + JAVA_TEMPLATE, MTX_BANNER, MTX_TYPE, SECTIONS, ConversionError, GraphStats, - JAVA_START, - JAVA_TEMPLATE, build_archive, c_alias_cnf, cnf_lite, @@ -33,6 +31,7 @@ verify_conversion, write_cnf, ) +from pyformlang.cfg import CFG, Production, Terminal, Variable def write_csv(path: pathlib.Path, lines) -> pathlib.Path: @@ -123,14 +122,14 @@ def test_convert_roundtrip_property(tmp_path): for _ in range(2000) ] csv = tmp_path / "g.csv" - csv.write_text("\n".join(f"{u} {v} {l}" for u, v, l in edges) + "\n") + csv.write_text("\n".join(f"{u} {v} {label}" for u, v, label in edges) + "\n") graph_dir = tmp_path / "graph" stats = convert_csv_to_graph_dir(csv, graph_dir) assert stats.total_edges == len(edges) assert Counter(stats.edges_per_label.values()) == Counter( - Counter(l for _, _, l in edges).values() + Counter(label for _, _, label in edges).values() ) restored = Counter() @@ -383,17 +382,10 @@ def test_c_alias_cnf_golden(tmp_path): ) EXPECTED_RDF_SUBCLASSOF_CNf = ( - "S\tsubClassOf_r\tN1\n" - "N1\tS\tsubClassOf\n" - "S\tsubClassOf_r\tsubClassOf\n" - "\n" - "Count:\n" - "S\n" + "S\tsubClassOf_r\tN1\nN1\tS\tsubClassOf\nS\tsubClassOf_r\tsubClassOf\n\nCount:\nS\n" ) -EXPECTED_RDF_TYPE_CNf = ( - "S\ttype_r\tN1\n" "N1\tS\ttype\n" "S\ttype_r\ttype\n" "\n" "Count:\n" "S\n" -) +EXPECTED_RDF_TYPE_CNf = "S\ttype_r\tN1\nN1\tS\ttype\nS\ttype_r\ttype\n\nCount:\nS\n" EXPECTED_RDF_BROADER_TRANSITIVE_CNf = ( "S\tbroaderTransitive\tN1\n" diff --git a/tests/utils/test_migrate_gdrive_to_s3.py b/tests/utils/test_migrate_gdrive_to_s3.py index c65d6dc5..e1e06c14 100644 --- a/tests/utils/test_migrate_gdrive_to_s3.py +++ b/tests/utils/test_migrate_gdrive_to_s3.py @@ -5,8 +5,6 @@ from unittest import mock import pytest - -from cfpq_data.dataset import DATASET_KEY_PREFIX, DATASET_URL from migrate_gdrive_to_s3 import ( DRIVE_DOWNLOAD_URL, DriveDownloadError, @@ -14,7 +12,6 @@ MigrationItem, discover_items, download_from_drive, - is_on_yandex, load_mapping, main, migrate, @@ -23,6 +20,8 @@ update_docs, ) +from cfpq_data.dataset import DATASET_KEY_PREFIX, DATASET_URL + def _rst_page(full_name: str, direct_fid: str, origin_fid: str | None = None) -> str: origin = "" diff --git a/tests/utils/test_upload_to_s3.py b/tests/utils/test_upload_to_s3.py index 3598f5ec..f308010e 100644 --- a/tests/utils/test_upload_to_s3.py +++ b/tests/utils/test_upload_to_s3.py @@ -1,7 +1,6 @@ from unittest import mock import pytest - from upload_to_s3 import ( DEFAULT_BUCKET, DEFAULT_ENDPOINT_URL, diff --git a/utils/convert_old_to_new.py b/utils/convert_old_to_new.py index d67d6ad5..0fa6624f 100644 --- a/utils/convert_old_to_new.py +++ b/utils/convert_old_to_new.py @@ -24,31 +24,31 @@ import tarfile import tempfile from dataclasses import dataclass, field -from typing import Dict, IO, Iterator, List, Optional, Sequence, Set, Tuple, Union +from typing import IO, Dict, Iterator, List, Optional, Sequence, Set, Tuple, Union import requests from botocore.client import BaseClient +from migrate_gdrive_to_s3 import sha256_of +from upload_to_s3 import ( + DEFAULT_BUCKET, + DEFAULT_ENDPOINT_URL, + create_s3_client, + upload_file, +) from cfpq_data.dataset import ( DATASET_KEY_PREFIX, DATASET_URL, LEGACY_VERSION_PREFIX, ) - -#: The old-format graph archives still live under the legacy version prefix. -OLD_FORMAT_GRAPH_URL = ( - f"https://cfpq-data.storage.yandexcloud.net/{LEGACY_VERSION_PREFIX}/graph/" -) from cfpq_data.grammars.generators.c_alias_grammar import c_alias_grammar from cfpq_data.grammars.generators.nested_parentheses_grammar import ( nested_parentheses_grammar, ) -from migrate_gdrive_to_s3 import sha256_of -from upload_to_s3 import ( - DEFAULT_BUCKET, - DEFAULT_ENDPOINT_URL, - create_s3_client, - upload_file, + +#: The old-format graph archives still live under the legacy version prefix. +OLD_FORMAT_GRAPH_URL = ( + f"https://cfpq-data.storage.yandexcloud.net/{LEGACY_VERSION_PREFIX}/graph/" ) __all__ = [ @@ -1028,8 +1028,7 @@ def verify_public_read(key: str) -> None: with requests.get(url, stream=True, timeout=600) as response: if response.status_code != 200: raise ConversionError( - f"Object {url} is not publicly readable " - f"(HTTP {response.status_code})" + f"Object {url} is not publicly readable (HTTP {response.status_code})" ) total = 0 for chunk in response.iter_content(chunk_size=1024 * 1024): diff --git a/utils/migrate_gdrive_to_s3.py b/utils/migrate_gdrive_to_s3.py index af973cf3..b6e17ddc 100644 --- a/utils/migrate_gdrive_to_s3.py +++ b/utils/migrate_gdrive_to_s3.py @@ -17,8 +17,6 @@ from dataclasses import dataclass import requests - -from cfpq_data.dataset import DATASET, DATASET_KEY_PREFIX, DATASET_URL from upload_to_s3 import ( DEFAULT_BUCKET, DEFAULT_ENDPOINT_URL, @@ -26,6 +24,8 @@ upload_file, ) +from cfpq_data.dataset import DATASET, DATASET_KEY_PREFIX, DATASET_URL + __all__ = [ "MigrationItem", "DriveDownloadError", @@ -397,8 +397,7 @@ def migrate( f"{local_path} for inspection." ) logging.info( - f"{key_name}: content identical to the stored copy, " - f"skipping upload" + f"{key_name}: content identical to the stored copy, skipping upload" ) summary["skipped_duplicate"] += 1 elif is_on_yandex(key_name): @@ -504,8 +503,7 @@ def main(argv: list[str] | None = None) -> None: parser.add_argument( "--dry-run", action="store_true", - help="report the plan without downloading, uploading or modifying " - "docs/mapping", + help="report the plan without downloading, uploading or modifying docs/mapping", ) args = parser.parse_args(argv) From 5878e10cbe82d83f288cfc9fd59bb8f082593ce3 Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 10:15:06 +0300 Subject: [PATCH 008/277] feat(37-S4): add ty + pyright type checking and fix all findings Add [tool.ty.environment] (extra-paths = ["utils"]) and [tool.pyright] (pythonVersion 3.11, extraPaths ["utils"], exclude the gitignored temporal_cfpq scratch dir) to pyproject.toml. ty is the fast local check; CI runs both ty and pyright (S6). Fixes: - Labeled graph generators: labels/choice annotated Sequence[str] instead of List[str]/Iterable[str], so the random.choice default and the string defaults type-check (behavior unchanged). - cfg.py: explicit None checks for re.search results (replacing the try/except AttributeError idiom) and for RSA.get_box; pass start_symbol.value to Regex.to_cfg, whose parameter is typed str. - rsa.py: None checks for Regex.to_epsilon_nfa and RSA.get_box results. - utils/convert_old_to_new.py: cnf_lite/instantiate_template/write_cnf accept Sequence instead of List (read-only iteration; fixes List invariance at call sites). - docs/conf.py: annotate the intersphinx retry wrapper to match sphinx.util.requests.get; retries/backoff become module constants. - Tests: cast get_words() results to list[Terminal] for CFG.contains (pyformlang annotates the two inconsistently); dummy BaseClient via cast for convert_one (the client only reaches monkeypatched helpers). One suppression, per the plan's false-positive clause: the _sphinx_requests.get rebind in docs/conf.py carries a bare "# type: ignore" because ty (invalid-assignment) rejects a signature-identical rebind of a module attribute that pyright accepts. Also records S1-S3 completion hashes in the detailed plan. ty check: 0 diagnostics; pyright: 0 errors; ruff clean; 342 tests pass. --- CHANGELOG.md | 7 +++++ cfpq_data/grammars/converters/cfg.py | 19 ++++++------- cfpq_data/grammars/readwrite/rsa.py | 7 ++++- .../generators/fast_labeled_binomial_graph.py | 10 +++---- .../labeled_barabasi_albert_graph.py | 10 +++---- .../generators/labeled_binomial_graph.py | 10 +++---- .../generators/labeled_scale_free_graph.py | 10 +++---- docs/conf.py | 28 +++++++++++++------ pyproject.toml | 9 ++++++ tasks/detailed_plan.md | 6 ++-- .../converters/test_cfg_converters.py | 6 ++++ .../converters/test_cnf_converters.py | 6 ++++ tests/utils/test_convert_old_to_new.py | 12 ++++++-- utils/convert_old_to_new.py | 12 ++++---- 14 files changed, 101 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3769c806..1234a442 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Ruff as the linting and formatting gate (rules `E`, `F`, `W`, `I` plus `ruff format`), replacing black; the codebase was brought in line in a one-time pass. +- Type checking with [ty](https://docs.astral.sh/ty/) for fast local checks + and Pyright in CI; the package, tests, and utility scripts are now fully + type-checked. ### Changed @@ -23,6 +26,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 dependency groups (`dev`, `test`, `docs`) instead of Poetry groups and the `setup.py` extras, a committed `uv.lock`, and all CI workflows on `astral-sh/setup-uv`. +- The labeled graph generators type their `labels` parameter as + `Sequence[str]`, correctly accepting both a single label string and a + sequence of labels (previously annotated `List[str]` despite the string + default). ### Removed diff --git a/cfpq_data/grammars/converters/cfg.py b/cfpq_data/grammars/converters/cfg.py index 08597abc..eb0c523f 100644 --- a/cfpq_data/grammars/converters/cfg.py +++ b/cfpq_data/grammars/converters/cfg.py @@ -77,7 +77,7 @@ def cfg_from_regex(regex: Regex, *, start_symbol: Variable = Variable("S")) -> C .. [1] https://en.wikipedia.org/wiki/Context-free_grammar#Formal_definitions .. [2] https://en.wikipedia.org/wiki/Regular_expression#Formal_definition """ - cfg = regex.to_cfg(start_symbol) + cfg = regex.to_cfg(start_symbol.value) logging.info(f"Create {cfg=} from {regex=}") @@ -119,7 +119,10 @@ def cfg_from_rsa(rsa: RSA) -> CFG: productions = set() for symbol in rsa.labels: - dfa = rsa.get_box(symbol).dfa + box = rsa.get_box(symbol) + if box is None: + raise ValueError(f"RSA has no box for label {symbol.value}") + dfa = box.dfa variables.add(Variable(symbol.value)) @@ -135,18 +138,14 @@ def cfg_from_rsa(rsa: RSA) -> CFG: for v, label, to in dfa._transition_function.get_edges(): if label.value == label.value.lower(): - try: - label_value = re.search('"TER:(.*)"', label.value).group(1) - except AttributeError: - label_value = label.value + match = re.search('"TER:(.*)"', label.value) + label_value = match.group(1) if match is not None else label.value terminals.add(Terminal(label_value)) production_label = Terminal(label_value) else: - try: - label_value = re.search('"VAR:(.*)"', label.value).group(1) - except AttributeError: - label_value = label.value + match = re.search('"VAR:(.*)"', label.value) + label_value = match.group(1) if match is not None else label.value production_label = Variable(label_value) diff --git a/cfpq_data/grammars/readwrite/rsa.py b/cfpq_data/grammars/readwrite/rsa.py index 1d570acd..ae629238 100644 --- a/cfpq_data/grammars/readwrite/rsa.py +++ b/cfpq_data/grammars/readwrite/rsa.py @@ -70,7 +70,10 @@ def rsa_from_text(text: str, *, start_symbol: Symbol = Symbol("S")) -> RSA: productions[head] = body for head, body in productions.items(): - boxes.add(Box(Regex(body).to_epsilon_nfa().minimize(), to_symbol(head))) + nfa = Regex(body).to_epsilon_nfa() + if nfa is None: + raise ValueError(f"Cannot build an epsilon NFA for {body=}") + boxes.add(Box(nfa.minimize(), to_symbol(head))) rsa = RSA(labels=labels, initial_label=start_symbol, boxes=boxes) @@ -111,6 +114,8 @@ def rsa_to_text(rsa: RSA) -> str: for symbol in rsa.labels: box = rsa.get_box(symbol) + if box is None: + raise ValueError(f"RSA has no box for label {symbol.value}") productions.append(f"{box.label.value} -> {box.dfa.to_regex()}") productions.sort( diff --git a/cfpq_data/graphs/generators/fast_labeled_binomial_graph.py b/cfpq_data/graphs/generators/fast_labeled_binomial_graph.py index b82162a3..5d835d6b 100644 --- a/cfpq_data/graphs/generators/fast_labeled_binomial_graph.py +++ b/cfpq_data/graphs/generators/fast_labeled_binomial_graph.py @@ -3,7 +3,7 @@ import logging import random -from typing import Callable, List, Union +from typing import Callable, Sequence, Union import networkx as nx @@ -14,8 +14,8 @@ def fast_labeled_binomial_graph( n: int, p: float, *, - labels: List[str] = "a", - choice: Callable[[List[str]], str] = random.choice, + labels: Sequence[str] = "a", + choice: Callable[[Sequence[str]], str] = random.choice, seed: Union[int, None] = None, ) -> nx.MultiDiGraph: """Returns a $G_{n,p}$ random graph, also known as an Erdős-Rényi graph or @@ -31,10 +31,10 @@ def fast_labeled_binomial_graph( p : float Probability for edge creation. - labels: Iterable[str] + labels: Sequence[str] Labels that will be used to mark the edges of the graph. - choice: Callable[[Iterable[str]], str] + choice: Callable[[Sequence[str]], str] Function for marking edges. seed : integer, random_state, or None (default) diff --git a/cfpq_data/graphs/generators/labeled_barabasi_albert_graph.py b/cfpq_data/graphs/generators/labeled_barabasi_albert_graph.py index 5f05d6f6..0a7e823a 100644 --- a/cfpq_data/graphs/generators/labeled_barabasi_albert_graph.py +++ b/cfpq_data/graphs/generators/labeled_barabasi_albert_graph.py @@ -7,7 +7,7 @@ import logging import random -from typing import Callable, List, Union +from typing import Callable, Sequence, Union import networkx as nx @@ -18,8 +18,8 @@ def labeled_barabasi_albert_graph( n: int, m: int, *, - labels: List[str] = "abcd", - choice: Callable[[List[str]], str] = random.choice, + labels: Sequence[str] = "abcd", + choice: Callable[[Sequence[str]], str] = random.choice, seed: Union[int, None] = None, ) -> nx.MultiDiGraph: """Returns a random graph according to the Barabási–Albert @@ -36,10 +36,10 @@ def labeled_barabasi_albert_graph( m : int Number of edges to attach from a new node to existing nodes. - labels: Iterable[str] + labels: Sequence[str] Labels that will be used to mark the edges of the graph. - choice: Callable[[Iterable[str]], str] + choice: Callable[[Sequence[str]], str] Function for marking edges. seed : int or None diff --git a/cfpq_data/graphs/generators/labeled_binomial_graph.py b/cfpq_data/graphs/generators/labeled_binomial_graph.py index 14993263..2955ea7b 100644 --- a/cfpq_data/graphs/generators/labeled_binomial_graph.py +++ b/cfpq_data/graphs/generators/labeled_binomial_graph.py @@ -4,7 +4,7 @@ import logging import random -from typing import Callable, List, Union +from typing import Callable, Sequence, Union import networkx as nx @@ -15,8 +15,8 @@ def labeled_binomial_graph( n: int, p: float, *, - labels: List[str] = "a", - choice: Callable[[List[str]], str] = random.choice, + labels: Sequence[str] = "a", + choice: Callable[[Sequence[str]], str] = random.choice, seed: Union[int, None] = None, ) -> nx.MultiDiGraph: """Returns a $G_{n,p}$ random graph, also known as an Erdős-Rényi graph or @@ -32,10 +32,10 @@ def labeled_binomial_graph( p : float Probability for edge creation. - labels: Iterable[str] + labels: Sequence[str] Labels that will be used to mark the edges of the graph. - choice: Callable[[Iterable[str]], str] + choice: Callable[[Sequence[str]], str] Function for marking edges. seed : integer, random_state, or None (default) diff --git a/cfpq_data/graphs/generators/labeled_scale_free_graph.py b/cfpq_data/graphs/generators/labeled_scale_free_graph.py index 66a0be59..628e1de5 100644 --- a/cfpq_data/graphs/generators/labeled_scale_free_graph.py +++ b/cfpq_data/graphs/generators/labeled_scale_free_graph.py @@ -2,7 +2,7 @@ import logging import random -from typing import Callable, Iterable, Union +from typing import Callable, Sequence, Union import networkx as nx @@ -17,8 +17,8 @@ def labeled_scale_free_graph( gamma: float = 0.05, delta_in: float = 0.2, delta_out: float = 0, - labels: Iterable[str] = "abcd", - choice: Callable[[Iterable[str]], str] = random.choice, + labels: Sequence[str] = "abcd", + choice: Callable[[Sequence[str]], str] = random.choice, seed: Union[int, None] = None, ) -> nx.MultiDiGraph: """Returns a scale-free directed graph. With labeled edges. @@ -48,10 +48,10 @@ def labeled_scale_free_graph( delta_out : float Bias for choosing nodes from out-degree distribution. - labels: Iterable[str] + labels: Sequence[str] Labels that will be used to mark the edges of the graph. - choice: Callable[[Iterable[str]], str] + choice: Callable[[Sequence[str]], str] Function for marking edges. seed : integer, random_state, or None (default) diff --git a/docs/conf.py b/docs/conf.py index 062edc68..0c278ea5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -76,7 +76,8 @@ # The default options for autodoc directives. # They are applied to all autodoc directives automatically. # It must be a dictionary which maps option names to the values. -# Setting None or True to the value is equivalent to giving only the option name to the directives. +# Setting None or True to the value is equivalent to giving only the option +# name to the directives. autodoc_default_options = { "members": True, } @@ -137,7 +138,8 @@ # The name of the Pygments (syntax highlighting) style to use. pygments_style = "borland" -# A list of prefixes that are ignored when creating the module index. (new in Sphinx 0.6) +# A list of prefixes that are ignored when creating the module index. +# (new in Sphinx 0.6) modindex_common_prefix = ["cfpq_data."] doctest_global_setup = "import cfpq_data" @@ -235,7 +237,9 @@ # transient connection errors; when all attempts fail, the error propagates # and the build still fails. import time as _time +from typing import Any +from requests import Response from requests.exceptions import ConnectionError as _RequestsConnectionError from requests.exceptions import Timeout as _RequestsTimeout from sphinx.util import requests as _sphinx_requests @@ -243,17 +247,25 @@ _orig_intersphinx_get = _sphinx_requests.get -def _get_with_retries(url, *args, retries=3, backoff=2.0, **kwargs): - for attempt in range(retries + 1): +_RETRY_COUNT = 3 +_RETRY_BACKOFF = 2.0 + + +def _get_with_retries(url: str, **kwargs: Any) -> Response: + attempt = 0 + while True: try: - return _orig_intersphinx_get(url, *args, **kwargs) + return _orig_intersphinx_get(url, **kwargs) except (_RequestsConnectionError, _RequestsTimeout): - if attempt == retries: + if attempt == _RETRY_COUNT: raise - _time.sleep(backoff * (attempt + 1)) + attempt += 1 + _time.sleep(_RETRY_BACKOFF * attempt) -_sphinx_requests.get = _get_with_retries +# ty rejects this signature-identical rebind of a module attribute (pyright +# accepts it), so the assignment is suppressed for it. +_sphinx_requests.get = _get_with_retries # type: ignore # The reST default role (used for this markup: `text`) to use for all # documents. diff --git a/pyproject.toml b/pyproject.toml index 05152e33..956da919 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -89,6 +89,15 @@ select = ["E", "F", "W", "I"] "docs/conf.py" = ["E402"] "tests/utils/conftest.py" = ["E402"] +[tool.ty.environment] +extra-paths = ["utils"] + +[tool.pyright] +pythonVersion = "3.11" +extraPaths = ["utils"] +# Local scratch/working directory (gitignored), not part of the package. +exclude = ["temporal_cfpq"] + [tool.pytest.ini_options] addopts = "--doctest-modules -vv -s" testpaths = ["cfpq_data", "tests"] diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index dc2dd111..b6982d42 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -96,7 +96,7 @@ Decisions made before implementation (user-confirmed where noted): ## Subtasks -### S1: Record task 37 in the task log and write this detailed plan +### S1: Record task 37 in the task log and write this detailed plan [done — 2516b06] **Code:** none (documentation-only) **Tests:** skip — no code to test @@ -108,7 +108,7 @@ Decisions made before implementation (user-confirmed where noted): verbatim (official uv pre-commit hooks; ty fast / ty+pyright in CI; delete the two broken scripts). -### S2: Core uv migration — PEP 621 pyproject, lockfile, legacy removal +### S2: Core uv migration — PEP 621 pyproject, lockfile, legacy removal [done — 3f69e99] **Code:** Rewrite `pyproject.toml` (PEP 621 `[project]`, `[dependency-groups]`, hatchling `[build-system]` + @@ -138,7 +138,7 @@ Decisions made before implementation (user-confirmed where noted): - Reuse: `utils/check_version_sync.py` / `utils/bump_version.py` unchanged (verified compatible with PEP 621). -### S3: Ruff lint + format config and one-time code pass +### S3: Ruff lint + format config and one-time code pass [done — a3def54] **Code:** Add `[tool.ruff]` (`target-version = "py311"`), `[tool.ruff.lint]` (`select = ["E", "F", "W", "I"]`) and diff --git a/tests/grammars/converters/test_cfg_converters.py b/tests/grammars/converters/test_cfg_converters.py index 2b9e4fec..a427fd5b 100644 --- a/tests/grammars/converters/test_cfg_converters.py +++ b/tests/grammars/converters/test_cfg_converters.py @@ -1,4 +1,7 @@ +from typing import cast + import pytest +from pyformlang.cfg import Terminal import cfpq_data @@ -16,6 +19,7 @@ def test_cfg_from_cnf(cnf): cfg = cfpq_data.cfg_from_cnf(cnf) for word in cfg.get_words(4): + word = cast("list[Terminal]", word) assert cfg.contains(word) and cnf.contains(word) @@ -23,6 +27,7 @@ def test_cfg_from_cnf(cnf): def test_cfg_from_regex(regex): cfg = cfpq_data.cfg_from_regex(regex) for word in cfg.get_words(4): + word = cast("list[Terminal]", word) regex_word = map(lambda x: x.value, word) assert cfg.contains(word) and regex.accepts(regex_word) @@ -32,4 +37,5 @@ def test_cfg_from_rsa(rsa): cfg = cfpq_data.cfg_from_rsa(rsa) cnf = cfpq_data.cnf_from_rsa(rsa) for word in cfg.get_words(4): + word = cast("list[Terminal]", word) assert cfg.contains(word) and cnf.contains(word) diff --git a/tests/grammars/converters/test_cnf_converters.py b/tests/grammars/converters/test_cnf_converters.py index da73dfff..ce245b59 100644 --- a/tests/grammars/converters/test_cnf_converters.py +++ b/tests/grammars/converters/test_cnf_converters.py @@ -1,4 +1,7 @@ +from typing import cast + import pytest +from pyformlang.cfg import Terminal import cfpq_data @@ -16,6 +19,7 @@ def test_cnf_from_cfg(cfg): cnf = cfpq_data.cnf_from_cfg(cfg) for word in cnf.get_words(4): + word = cast("list[Terminal]", word) assert cnf.contains(word) and cfg.contains(word) @@ -23,6 +27,7 @@ def test_cnf_from_cfg(cfg): def test_cnf_from_regex(regex): cnf = cfpq_data.cnf_from_regex(regex) for word in cnf.get_words(4): + word = cast("list[Terminal]", word) regex_word = map(lambda x: x.value, word) assert cnf.contains(word) and regex.accepts(regex_word) @@ -32,4 +37,5 @@ def test_cnf_from_rsa(rsa): cnf = cfpq_data.cnf_from_rsa(rsa) cfg = cfpq_data.cfg_from_rsa(rsa) for word in cnf.get_words(4): + word = cast("list[Terminal]", word) assert cnf.contains(word) and cfg.contains(word) diff --git a/tests/utils/test_convert_old_to_new.py b/tests/utils/test_convert_old_to_new.py index 2c50d32c..cdd26578 100644 --- a/tests/utils/test_convert_old_to_new.py +++ b/tests/utils/test_convert_old_to_new.py @@ -4,8 +4,10 @@ import shutil import tarfile from collections import Counter +from typing import cast import pytest +from botocore.client import BaseClient from convert_old_to_new import ( JAVA_START, JAVA_TEMPLATE, @@ -33,6 +35,10 @@ ) from pyformlang.cfg import CFG, Production, Terminal, Variable +# convert_one never touches the S3 client directly (all S3 calls go through +# the monkeypatched helpers), so a stand-in satisfies the annotation. +_DUMMY_CLIENT = cast(BaseClient, object()) + def write_csv(path: pathlib.Path, lines) -> pathlib.Path: path.write_text("\r\n".join(lines) + "\r\n") @@ -723,7 +729,7 @@ def fake_upload(client, local_path, bucket, key=None): result = conv.convert_one( "g", "c_alias", - client=object(), + client=_DUMMY_CLIENT, bucket="cfpq-data", key_prefix="5.0.0/graph", record=record, @@ -750,7 +756,7 @@ def failing_download(name, dest_dir): result2 = conv.convert_one( "g", "c_alias", - client=object(), + client=_DUMMY_CLIENT, bucket="cfpq-data", key_prefix="5.0.0/graph", record=record, @@ -766,7 +772,7 @@ def failing_download(name, dest_dir): result3 = conv.convert_one( "g", "c_alias", - client=object(), + client=_DUMMY_CLIENT, bucket="cfpq-data", key_prefix="5.0.0/graph", record=record, diff --git a/utils/convert_old_to_new.py b/utils/convert_old_to_new.py index 0fa6624f..6cb37812 100644 --- a/utils/convert_old_to_new.py +++ b/utils/convert_old_to_new.py @@ -311,7 +311,7 @@ def convert_csv_to_graph_dir( JAVA_START = "PT" -def cnf_lite(productions: List[Tuple[str, Tuple[str, ...]]]): +def cnf_lite(productions: Sequence[Tuple[str, Tuple[str, ...]]]): """Break productions with a right-hand side of more than two symbols. The ``.cnf`` format allows at most two symbols on the right-hand side. @@ -323,7 +323,7 @@ def cnf_lite(productions: List[Tuple[str, Tuple[str, ...]]]): Parameters ---------- - productions : list of (str, tuple of str) + productions : sequence of (str, tuple of str) The productions as ``(lhs, rhs)`` pairs in the desired output order. Returns @@ -348,7 +348,7 @@ def cnf_lite(productions: List[Tuple[str, Tuple[str, ...]]]): def write_cnf( - productions: List[Tuple[str, Tuple[str, ...]]], + productions: Sequence[Tuple[str, Tuple[str, ...]]], start_symbol: str, path: Union[pathlib.Path, str], ) -> None: @@ -360,7 +360,7 @@ def write_cnf( Parameters ---------- - productions : list of (str, tuple of str) + productions : sequence of (str, tuple of str) The productions as ``(lhs, rhs)`` pairs in the desired output order. start_symbol : str The start non-terminal. @@ -489,7 +489,7 @@ def rdf_cnf_grammars( def instantiate_template( - template: List[Tuple[str, Tuple[str, ...]]], + template: Sequence[Tuple[str, Tuple[str, ...]]], index_sets: Dict[str, Set[int]], ) -> List[Tuple[str, Tuple[str, ...]]]: """Expand the indexed symbols of a template per concrete index. @@ -507,7 +507,7 @@ def instantiate_template( Parameters ---------- - template : list of (str, tuple of str) + template : sequence of (str, tuple of str) The template productions with placeholder indexed symbols. index_sets : dict of str -> set of int Indexed symbol -> the concrete indices present in the graph. From 2f34ee33b39a44c78e3ef694e7614bdc7ec3f33b Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 10:24:05 +0300 Subject: [PATCH 009/277] feat(37-S5): rewrite pre-commit config with the official uv and ruff hooks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the black hook with the official astral-sh hooks: uv-pre-commit 0.12.15 (uv-lock) and ruff-pre-commit v0.16.7 (ruff-check --fix, ruff-format), bump pre-commit-hooks to v6.0.0 and drop requirements-txt-fixer (there is no requirements.txt anymore). Add a local ty-check hook (uv run ty check) alongside the existing version-sync hook. docs/developer.rst: replace the "Pre-commit" section with "Quality checks" — the config file stays the single source of truth for the hook list, the ruff-pre-commit rev must match the locked ruff version, local commands are uv run ruff check/format and uv run ty check, and CI additionally runs Pyright (ty is the fast local check). Update the Test pipeline commands to uv run pytest and add type checking to the quality gate list. pre-commit run --all-files: all 8 hooks pass. Also records the S4 completion hash in the detailed plan. --- .pre-commit-config.yaml | 23 ++++++++++++++++++----- docs/developer.rst | 40 ++++++++++++++++++++++++---------------- tasks/detailed_plan.md | 2 +- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6e45b4ae..a592c88b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,15 +1,22 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v6.0.0 hooks: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - - id: requirements-txt-fixer - - repo: https://github.com/psf/black - rev: 22.10.0 + - repo: https://github.com/astral-sh/uv-pre-commit + # uv version. + rev: 0.12.15 hooks: - - id: black + - id: uv-lock + - repo: https://github.com/astral-sh/ruff-pre-commit + # Must match the ruff version locked in uv.lock. + rev: v0.16.7 + hooks: + - id: ruff-check + args: [--fix] + - id: ruff-format - repo: local hooks: - id: check-version-sync @@ -18,3 +25,9 @@ repos: language: system pass_filenames: false always_run: true + - id: ty-check + name: ty type check + entry: uv run ty check + language: system + pass_filenames: false + files: \.py$ diff --git a/docs/developer.rst b/docs/developer.rst index edaf439a..fa26ca5d 100644 --- a/docs/developer.rst +++ b/docs/developer.rst @@ -37,31 +37,38 @@ CI workflows install their dependencies through it: distribution's install requirements on PyPI; the Poetry groups in ``pyproject.toml`` drive the development environment and CI. -.. _developer-precommit: +.. _developer-quality: -Pre-commit ----------- +Quality checks +-------------- -Formatting and hygiene checks run through ``pre-commit``. The hook list — -black formatting plus whitespace, YAML, and requirements-file fixers, and a -version-sync check that fails when :file:`cfpq_data/config.py` and -:file:`pyproject.toml` declare different versions — is defined in +Linting, formatting, and type checking are managed by uv and run through +``pre-commit``. The hook list — hygiene checks, the official ``uv-lock`` and +ruff hooks (check with autofix plus format), a version-sync check that fails +when :file:`cfpq_data/config.py` and :file:`pyproject.toml` declare different +versions, and a local ty type check — is defined in :file:`.pre-commit-config.yaml`, which is the source of truth; do not maintain a copy of it elsewhere. +The ``ruff-pre-commit`` hook revision must match the ruff version locked in +:file:`uv.lock`; bump both together when upgrading ruff. + Install the git hook once so the checks run on every commit:: - pre-commit install + uv run pre-commit install Run the full pass manually (this is what CI does):: - pre-commit run --all-files --color always --verbose --show-diff-on-failure + uv run pre-commit run --all-files --color always --verbose --show-diff-on-failure -Format a single file with black directly:: +The individual tools can also be run directly:: - black + uv run ruff check . + uv run ruff format . + uv run ty check -CI runs this full pass on every push and pull request +CI additionally runs Pyright, the stricter of the two type checkers; ty is +the fast local check. The full pass runs on every push and pull request (:file:`.github/workflows/lint.yml`). .. _developer-tests: @@ -74,11 +81,11 @@ sections of public docstrings are executed as tests, so the documented behavior and the tested behavior are the same code. The canonical local command (the one CI runs):: - poetry run pytest --doctest-modules -vv -s cfpq_data tests + uv run pytest A single module or function:: - poetry run pytest tests/graphs/utils/test_add_reverse_edges.py + uv run pytest tests/graphs/utils/test_add_reverse_edges.py - Doctest discovery and test paths are configured in ``pyproject.toml`` (``[tool.pytest.ini_options]``). @@ -167,8 +174,9 @@ no exceptions: 1. The full test suite: 0 failures, 0 skipped. 2. The full pre-commit pass: no errors. -3. The docs build: exit 0 under the no-warnings policy. -4. The link check: no broken or timed-out links. +3. Type checking: ``uv run ty check`` and Pyright both report no errors. +4. The docs build: exit 0 under the no-warnings policy. +5. The link check: no broken or timed-out links. Merge strategy ~~~~~~~~~~~~~~ diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index b6982d42..0b4e710b 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -161,7 +161,7 @@ Decisions made before implementation (user-confirmed where noted): - `ruff format` must not change doctest output (it does not touch docstrings); the suite is the guard. -### S4: Type checking — ty + pyright config and error fixes +### S4: Type checking — ty + pyright config and error fixes [done — 5878e10] **Code:** Add `[tool.ty.environment]` (`extra-paths = ["utils"]`) and `[tool.pyright]` (`pythonVersion = "3.11"`, `extraPaths = ["utils"]`) From 73eb75d81819e321676aa26ef766ff31e66242b1 Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 10:29:40 +0300 Subject: [PATCH 010/277] feat(37-S6): migrate all CI workflows from Poetry to uv Replace actions/setup-python + pip-installed Poetry with astral-sh/setup-uv@v10 in tests, coverage, docs, deploy_docs, lint and publish. Dependencies install via 'uv sync --frozen --only-group ' (test/docs/dev per job; --frozen fails on a stale uv.lock) which also installs the project itself, so the 'pip install .' steps are dropped; 'poetry show' becomes 'uv tree'. The publish build job builds with 'uv build' instead of pip-installing python-build. The lint job moves to Python 3.11 (the project floor), runs pre-commit via 'uv run', and gains explicit 'uv run ty check' and 'uv run pyright' steps (Pyright is the stricter checker and only runs in CI). The pointless 'pre-commit install' step in CI is dropped. docs/release.rst: the packaging-constraint bullet now reflects PEP 621 + hatchling (all build inputs VCS-tracked; uv build builds the wheel from the source tree, not from the sdist) and the build command line says 'uv build'. All six workflow files parse as YAML; no poetry/setup-python references remain. Real CI runs on the next push after merge. --- .github/workflows/coverage.yml | 24 +++++++----------------- .github/workflows/deploy_docs.yml | 22 +++++++--------------- .github/workflows/docs.yml | 23 ++++++++--------------- .github/workflows/lint.yml | 24 ++++++++++++++++-------- .github/workflows/publish.yml | 6 ++---- .github/workflows/tests.yml | 23 +++++++---------------- docs/release.rst | 11 ++++++----- tasks/detailed_plan.md | 2 +- 8 files changed, 54 insertions(+), 81 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 2ef91bc4..b2fbef6a 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -11,30 +11,20 @@ jobs: steps: - uses: actions/checkout@v7 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v7 + - name: Set up uv with Python ${{ matrix.python-version }} + uses: astral-sh/setup-uv@v10 with: python-version: ${{ matrix.python-version }} - - name: Install Poetry - run: | - pip install poetry - - - name: Install dependencies with Poetry - run: | - poetry install --no-interaction --no-ansi --with dev,test + # --frozen fails if uv.lock is out of sync with pyproject.toml. + - name: Install dependencies with uv + run: uv sync --frozen --only-group test - name: Show installed packages - run: poetry show - - - name: Install packages - run: | - python -m pip install . - + run: uv tree - name: Test CFPQ_Data with coverage - run: | - poetry run pytest --cov=cfpq_data --doctest-modules -vv -s cfpq_data tests + run: uv run pytest --cov=cfpq_data - name: Upload coverage to Codecov uses: codecov/codecov-action@v7 diff --git a/.github/workflows/deploy_docs.yml b/.github/workflows/deploy_docs.yml index 8b7babc1..216f5971 100644 --- a/.github/workflows/deploy_docs.yml +++ b/.github/workflows/deploy_docs.yml @@ -15,28 +15,20 @@ jobs: steps: - uses: actions/checkout@v7 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v7 + - name: Set up uv with Python ${{ matrix.python-version }} + uses: astral-sh/setup-uv@v10 with: python-version: ${{ matrix.python-version }} - - name: Install Poetry - run: | - pip install poetry - - - name: Install dependencies with Poetry - run: | - poetry install --no-interaction --no-ansi --with docs + # --frozen fails if uv.lock is out of sync with pyproject.toml. + - name: Install dependencies with uv + run: uv sync --frozen --only-group docs - name: Show installed packages - run: poetry show - - - name: Install packages - run: | - poetry run pip install . + run: uv tree - name: Build - run: poetry run make -C docs/ html + run: uv run make -C docs/ html - name: Deploy uses: JamesIves/github-pages-deploy-action@v4 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 8da9e03f..ca151745 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -11,31 +11,24 @@ jobs: steps: - uses: actions/checkout@v7 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v7 + - name: Set up uv with Python ${{ matrix.python-version }} + uses: astral-sh/setup-uv@v10 with: python-version: ${{ matrix.python-version }} - - name: Install Poetry - run: | - pip install poetry - - - name: Install dependencies with Poetry - run: | - poetry install --no-interaction --no-ansi --with docs + # --frozen fails if uv.lock is out of sync with pyproject.toml. + - name: Install dependencies with uv + run: uv sync --frozen --only-group docs - name: Show installed packages - run: poetry show - - - name: Install packages - run: poetry run pip install . + run: uv tree # No-warnings policy: the build runs with -W --keep-going (see # docs/Makefile), so any warning — including an unresolved # cross-reference under nitpicky — exits non-zero on its own. - name: Build - run: poetry run make -C docs/ html + run: uv run make -C docs/ html # The linkcheck builder exits non-zero on broken or timed-out links. - name: Check links - run: poetry run sphinx-build -b linkcheck docs docs/_build/linkcheck + run: uv run sphinx-build -b linkcheck docs docs/_build/linkcheck diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e3a80a63..acc24206 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -7,20 +7,28 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ 3.9 ] + python-version: [ 3.11 ] steps: - uses: actions/checkout@v7 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v7 + - name: Set up uv with Python ${{ matrix.python-version }} + uses: astral-sh/setup-uv@v10 with: python-version: ${{ matrix.python-version }} - - name: Install pre-commit - run: | - python -m pip install pre-commit==3.6.2 - pre-commit install + # --frozen fails if uv.lock is out of sync with pyproject.toml. + - name: Install dependencies with uv + run: uv sync --frozen --only-group dev - name: Run pre-commit run: | - pre-commit run --all-files --color always --verbose --show-diff-on-failure + uv run pre-commit run --all-files --color always --verbose --show-diff-on-failure + + # The pre-commit pass already runs ruff and ty as hooks; these steps + # make the type checks explicit — Pyright is the stricter checker and + # only runs here. + - name: Type check with ty + run: uv run ty check + + - name: Type check with Pyright + run: uv run pyright diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a7b23be3..1687a0f9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,7 +18,7 @@ jobs: steps: - uses: actions/checkout@v7 - - uses: actions/setup-python@v7 + - uses: astral-sh/setup-uv@v10 with: python-version: '3.11' @@ -35,9 +35,7 @@ jobs: echo "Tag ${GITHUB_REF_NAME} matches package version ${ver}" - name: Build distributions - run: | - python3 -m pip install --upgrade build - python3 -m build + run: uv build - name: Upload dist uses: actions/upload-artifact@v7 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2cbd38dc..017b1658 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,26 +16,17 @@ jobs: steps: - uses: actions/checkout@v7 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v7 + - name: Set up uv with Python ${{ matrix.python-version }} + uses: astral-sh/setup-uv@v10 with: python-version: ${{ matrix.python-version }} - - name: Install Poetry - run: | - pip install poetry - - - name: Install dependencies with Poetry - run: | - poetry install --no-interaction --no-ansi --with dev,test + # --frozen fails if uv.lock is out of sync with pyproject.toml. + - name: Install dependencies with uv + run: uv sync --frozen --only-group test - name: Show installed packages - run: poetry show - - - name: Install packages - run: | - python -m pip install . + run: uv tree - name: Test CFPQ_Data - run: | - poetry run pytest --doctest-modules -vv -s cfpq_data tests + run: uv run pytest diff --git a/docs/release.rst b/docs/release.rst index 8518adac..249e50e0 100644 --- a/docs/release.rst +++ b/docs/release.rst @@ -30,7 +30,7 @@ The ``publish`` workflow (``.github/workflows/publish.yml``) runs when a ``v*`` tag is pushed: 1. Verifies the tag matches the package version. -2. Builds the sdist and wheel (``python -m build``). +2. Builds the sdist and wheel (``uv build``). 3. Publishes to PyPI via **Trusted Publishing** (OIDC) — no stored token; a ``PYPI_API_TOKEN`` secret is supported as a fallback. 4. Creates a GitHub Release with the matching changelog section. @@ -46,10 +46,11 @@ be released. Two packaging constraints matter: -- ``python -m build`` builds the wheel *from the sdist*, so the sdist must - contain everything :file:`setup.py` reads at build time — in particular - ``requirements/*.txt``, included via :file:`MANIFEST.in`. The PR's Publish - check catches a missing file before a tag is cut. +- With PEP 621 metadata and hatchling, all build inputs are VCS-tracked and + ``uv build`` builds the wheel directly from the source tree (not from the + sdist), so nothing can be silently missing from a distribution. The PR's + TestPyPI pre-publish still validates the build and its metadata before a + tag is cut. - PyPI and TestPyPI reject re-uploads of files that already exist for a version. The PR check uses ``skip-existing`` to stay green; the real publish does not — if a tag push reaches PyPI and then fails, an owner must diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index 0b4e710b..f8444eeb 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -183,7 +183,7 @@ Decisions made before implementation (user-confirmed where noted): - pyright runs in its default `basic` mode; do not lower the mode to get green — fix or justify. -### S5: Rewrite .pre-commit-config.yaml with official hooks +### S5: Rewrite .pre-commit-config.yaml with official hooks [done — 2f34ee3] **Code:** New `.pre-commit-config.yaml`: - `pre-commit/pre-commit-hooks` v6.0.0: `check-yaml`, From 2c73ab7b00ad18341489bb0c60a1bbb4590034c2 Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 10:50:57 +0300 Subject: [PATCH 011/277] docs(37-S7): finish the uv migration in the remaining docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit docs/developer.rst: rewrite the Development setup section for uv — uv sync --all-groups pulls the three PEP 735 dependency groups and installs cfpq_data itself editable, so the Poetry/package-mode/setup.py/ requirements paragraphs are gone; the committed uv.lock is pinned and CI passes --frozen. docs/README.md: Poetry -> uv commands (uv sync --only-group docs, uv run make -C docs html, uv run sphinx-build linkcheck). README.rst: the For developers section now uses uv sync --all-groups and uv run for the local checks; 'pre-commit' is referred to as quality checks. docs/conf.py: set linkcheck_user_agent to a descriptive UA — Wikipedia answers 403 ('Too many requests') to generic client UAs from some networks while the pages remain valid, and their robot policy asks for a descriptive UA; without this the documented linkcheck gate cannot pass. Verified: make -C docs html exits 0 under the no-warnings policy and sphinx-build -b linkcheck reports no broken or timed-out links. Grep of docs + README for poetry/requirements/setup.py/MANIFEST is clean. Also records the S6 completion hash in the detailed plan. --- README.rst | 21 ++++++++++----------- docs/README.md | 20 +++++++++----------- docs/conf.py | 8 ++++++++ docs/developer.rst | 34 ++++++++++++++++------------------ tasks/detailed_plan.md | 2 +- 5 files changed, 44 insertions(+), 41 deletions(-) diff --git a/README.rst b/README.rst index 9011811a..d3866ad4 100644 --- a/README.rst +++ b/README.rst @@ -70,21 +70,20 @@ Load graph from Dataset For developers ************** -To work on CFPQ_Data itself, set up the development environment (Poetry):: +To work on CFPQ_Data itself, set up the development environment (uv):: - poetry install --with dev,test,docs - poetry run pip install . + uv sync --all-groups -and run the main local checks that CI enforces — tests, style, and the docs -build:: +and run the main local checks that CI enforces — tests, quality checks, and +the docs build:: - poetry run pytest --doctest-modules -vv -s cfpq_data tests - pre-commit run --all-files - poetry run make -C docs html + uv run pytest + uv run pre-commit run --all-files + uv run make -C docs html -The full developer guide — development setup, pre-commit, the test pipeline, -docs build and deployment, the package release process, and contribution -guidelines — is on the `Developer `_ page. +The full developer guide — development setup, quality checks, the test +pipeline, docs build and deployment, the package release process, and +contribution guidelines — is on the `Developer `_ page. How to add a new graph? *********************** diff --git a/docs/README.md b/docs/README.md index cba591d2..48be2777 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,21 +4,19 @@ We use Sphinx for generating the API and reference documentation. ## Instructions -Install the Python packages needed to build the documentation from the -Poetry docs group — the same one the CI workflows use:: +Install the Python packages needed to build the documentation from the uv +`docs` dependency group — the same one the CI workflows install:: - poetry install --with docs + uv sync --only-group docs -in the root directory. (`requirements/*.txt` are read by `setup.py` to -declare the distribution's install requirements on PyPI; the Poetry groups -in `pyproject.toml` drive the development environment and CI.) +in the root directory. -To build the HTML documentation, enter:: +To build the HTML documentation, run from the repository root:: - make html + uv run make -C docs html -in the ``doc/`` directory. This will generate a ``build/html`` subdirectory -containing the built documentation. +This will generate a ``docs/_build/html`` subdirectory containing the built +documentation. The build runs with the no-warnings policy (``-W --keep-going`` in ``docs/Makefile``): any Sphinx warning — including an unresolved @@ -30,7 +28,7 @@ warning in one run. Fix the warnings; do not suppress them. To check that all links in the documentation resolve (local targets against the filesystem, external URLs over HTTP), run from the repository root:: - sphinx-build -b linkcheck docs docs/_build/linkcheck + uv run sphinx-build -b linkcheck docs docs/_build/linkcheck The check runs in full — no URL classes are skipped by default; see ``linkcheck_ignore`` in ``docs/conf.py`` for the two documented exceptions. diff --git a/docs/conf.py b/docs/conf.py index 0c278ea5..28339228 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -92,6 +92,14 @@ # linkcheck: treat 401 responses as working (auth-required pages exist). linkcheck_allow_unauthorized = True +# linkcheck: identify with a descriptive User-Agent. Wikipedia answers 403 +# ("Too many requests") to generic client UAs from some networks while the +# pages remain valid; their robot policy asks for a descriptive UA. +linkcheck_user_agent = ( + "CFPQ_Data-docs-linkcheck " + "(https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data)" +) + # linkcheck: skip exactly these two hosts. Both answer 403 to datacenter # clients (verified 2026-09: a browser User-Agent still gets 403, so the # blocking is IP-based) while the pages remain valid for human readers — diff --git a/docs/developer.rst b/docs/developer.rst index fa26ca5d..af0ee367 100644 --- a/docs/developer.rst +++ b/docs/developer.rst @@ -18,24 +18,22 @@ Development setup ----------------- CFPQ_Data requires Python 3.11–3.13 (``pyproject.toml`` declares -``>=3.11,<3.14``). The canonical development environment is **Poetry** — all -CI workflows install their dependencies through it: - -.. code-block:: bash - - poetry install --with dev,test,docs - poetry run pip install . - -- ``--with dev,test,docs`` pulls the three dependency groups from - ``pyproject.toml``: developer tools (``black``, ``pre-commit``, ``pytest``, - ``boto3``), test extras (``pytest-cov``, ``codecov``), and the Sphinx docs - stack. -- The project is declared with ``package-mode = false``, so Poetry installs - only the dependencies; ``poetry run pip install .`` then installs - ``cfpq_data`` itself from :file:`setup.py`. -- ``requirements/*.txt`` are read by :file:`setup.py` to declare the - distribution's install requirements on PyPI; the Poetry groups in - ``pyproject.toml`` drive the development environment and CI. +``>=3.11,<3.14``). The canonical development environment is **uv** — all CI +workflows install their dependencies through it. Install uv once (see the +`uv installation guide `_), +then from the repository root:: + + uv sync --all-groups + +- ``--all-groups`` pulls the three PEP 735 dependency groups from + ``pyproject.toml``: developer tools (``ruff``, ``ty``, ``pyright``, + ``pre-commit``, ``boto3``), test extras (``pytest``, ``pytest-cov``), and + the Sphinx docs stack. +- ``uv sync`` also installs ``cfpq_data`` itself (editable) into the project + environment, so no separate install step is needed; ``uv run ...`` executes + commands inside that environment. +- The committed :file:`uv.lock` pins every dependency; CI passes ``--frozen`` + to fail on a lockfile that is out of sync with ``pyproject.toml``. .. _developer-quality: diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index f8444eeb..de5c882f 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -213,7 +213,7 @@ Decisions made before implementation (user-confirmed where noted): - `uv run ty check` as a local hook requires uv on PATH — that is now a project prerequisite (documented in "Development setup"). -### S6: Migrate all CI workflows to uv +### S6: Migrate all CI workflows to uv [done — 73eb75d] **Code:** `.github/workflows/{tests,coverage,docs,deploy_docs,lint,publish}.yml`: replace `actions/setup-python` + Poetry with From 21a9333e60f60e6e87703d3080755c9ae21bc79b Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 10:56:42 +0300 Subject: [PATCH 012/277] docs(37-S8): point the agent skills at the uv toolchain run-tests: re-run under 'uv run' instead of 'poetry run'; the test-deps note now names the 'test' dependency group in pyproject.toml (codecov is gone). code-style: pointer moves from the old "Pre-commit" section to the new "Quality checks" section; the dev-deps note names the 'dev' group (ruff, ty, pyright, pre-commit) run via uv. quality-gates: add the type-check step (uv run ty check locally; CI additionally runs Pyright) and update the section reference. release: the version-guard command is 'uv run pre-commit run check-version-sync --all-files'. Grep of .opencode/skills/ for poetry: no matches. Also records the S7 completion hash in the detailed plan. --- .opencode/skills/code-style/SKILL.md | 14 ++++++++------ .opencode/skills/quality-gates/SKILL.md | 21 ++++++++++++--------- .opencode/skills/release/SKILL.md | 2 +- .opencode/skills/run-tests/SKILL.md | 7 ++++--- tasks/detailed_plan.md | 2 +- 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/.opencode/skills/code-style/SKILL.md b/.opencode/skills/code-style/SKILL.md index 166d5066..3656a992 100644 --- a/.opencode/skills/code-style/SKILL.md +++ b/.opencode/skills/code-style/SKILL.md @@ -1,15 +1,17 @@ --- name: code-style -description: Use before committing to format and lint CFPQ_Data. Thin pointer to the "Pre-commit" section of docs/developer.rst, which holds the model and the exact commands; the hook list is defined in .pre-commit-config.yaml. +description: Use before committing to format and lint CFPQ_Data. Thin pointer to the "Quality checks" section of docs/developer.rst, which holds the model and the exact commands; the hook list is defined in .pre-commit-config.yaml. --- # Code style -What pre-commit enforces, how CI runs it, and the exact local commands are -documented in the "Pre-commit" section of `docs/developer.rst` — the single -source of truth. Read that section before running anything. The hook list -lives in `.pre-commit-config.yaml`. +What the quality checks enforce (ruff lint/format, ty type check, hygiene +hooks), how CI runs them, and the exact local commands are documented in the +"Quality checks" section of `docs/developer.rst` — the single source of +truth. Read that section before running anything. The hook list lives in +`.pre-commit-config.yaml`. ## Notes -- Dev deps are in `requirements/developer.txt` (`black`, `pre-commit`, `pytest`). +- Dev tools (`ruff`, `ty`, `pyright`, `pre-commit`) live in the `dev` + dependency group in `pyproject.toml`; run them via `uv run`. diff --git a/.opencode/skills/quality-gates/SKILL.md b/.opencode/skills/quality-gates/SKILL.md index e865366f..877b0220 100644 --- a/.opencode/skills/quality-gates/SKILL.md +++ b/.opencode/skills/quality-gates/SKILL.md @@ -1,6 +1,6 @@ --- name: quality-gates -description: Use before merging a task to dev. Defines the hard gate that must pass (tests + style + docs build) and how to interpret its result. References docs/developer.rst for the exact commands. +description: Use before merging a task to dev. Defines the hard gate that must pass (tests + style + type check + docs build) and how to interpret its result. References docs/developer.rst for the exact commands. --- # Quality Gates @@ -10,13 +10,15 @@ states: **PASS** or **BLOCKED**. There is no "pass with exceptions". ## What the gate is -The gate is the combination of the test suite, the style/lint checks, and -the docs build: +The gate is the combination of the test suite, the style/lint checks, the +type check, and the docs build: - **Tests** — see the "Test pipeline" section of `docs/developer.rst` for the exact command. -- **Style/lint** — see the "Pre-commit" section of `docs/developer.rst` for - the exact command. +- **Style/lint** — see the "Quality checks" section of `docs/developer.rst` + for the exact command. +- **Type check** — `uv run ty check` must report no errors; CI additionally + runs Pyright (see the "Quality checks" section of `docs/developer.rst`). - **Docs build** — see the "Docs build and deploy" section of `docs/developer.rst` (and `docs/README.md`) for the exact command. It must exit 0. The build runs under the no-warnings policy (`-W --keep-going`, see @@ -35,13 +37,14 @@ skill only defines the gate semantics. 1. Run the full test suite ("Test pipeline" section of `docs/developer.rst`). It must show 0 failures and 0 skipped. -2. Run the full style/lint pass ("Pre-commit" section of +2. Run the full style/lint pass ("Quality checks" section of `docs/developer.rst`). It must show no errors. -3. Build the docs ("Docs build and deploy" section of `docs/developer.rst`). +3. Run the type check (`uv run ty check`). It must report no errors. +4. Build the docs ("Docs build and deploy" section of `docs/developer.rst`). It must exit 0 (no-warnings policy: any warning fails the build). -4. Run the link check ("Docs build and deploy" section of +5. Run the link check ("Docs build and deploy" section of `docs/developer.rst`). It must report no broken or timed-out links. -5. Interpret the result: +6. Interpret the result: - All clean → **PASS**. Proceed to merge (see `git-workflow`). - Any failure → **BLOCKED**. diff --git a/.opencode/skills/release/SKILL.md b/.opencode/skills/release/SKILL.md index b68a19c1..81cb1107 100644 --- a/.opencode/skills/release/SKILL.md +++ b/.opencode/skills/release/SKILL.md @@ -25,7 +25,7 @@ pre-publishes to TestPyPI as a packaging check. 2. Verify the version guard passes: ```bash - poetry run pre-commit run check-version-sync --all-files + uv run pre-commit run check-version-sync --all-files ``` 3. Commit the bump (message: `chore: release X.Y.Z`). 4. Merge `dev` into `master` via a pull request (`master` is protected; do diff --git a/.opencode/skills/run-tests/SKILL.md b/.opencode/skills/run-tests/SKILL.md index 0b9d0494..0eeeca4a 100644 --- a/.opencode/skills/run-tests/SKILL.md +++ b/.opencode/skills/run-tests/SKILL.md @@ -19,9 +19,10 @@ system Python on this machine has networkx 2.6.2, while the project pins in `cfpq_data/graphs/generators/fast_labeled_binomial_graph.py` depend on networkx's version-specific RNG behavior and fail spuriously under 2.6.2 (91 != 85, 182 != 177, 722 != 711). If a bare-pytest run shows exactly those -failures, re-run under `poetry run` before investigating — the suite is green -in the Poetry environment (networkx 3.6.1). +failures, re-run under `uv run` before investigating — the suite is green in +the uv project environment (networkx 3.6.1). ## Notes -- Test deps: `pytest`, `pytest-cov`, `codecov` (`requirements/tests.txt`). +- Test deps: `pytest`, `pytest-cov` (the `test` dependency group in + `pyproject.toml`). diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index de5c882f..f01d87f3 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -238,7 +238,7 @@ Decisions made before implementation (user-confirmed where noted): - `--frozen` makes CI fail if `uv.lock` is out of sync with `pyproject.toml` (the `uv-lock` pre-commit hook is the local guard). -### S7: Update remaining docs and verify the docs build +### S7: Update remaining docs and verify the docs build [done — 2c73ab7] **Code:** none (documentation-only) **Tests:** skip — no code to test From 07b4fb014287cc0459beab24008522611fee0495 Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 11:13:01 +0300 Subject: [PATCH 013/277] docs(37-S8): mark task 37 done in the task log All eight subtasks are merged to dev: uv migration (PEP 621 + hatchling, uv.lock, legacy removal), ruff lint/format gate, ty + pyright type checking, official pre-commit hooks, CI on astral-sh/setup-uv, docs and skills updated. Code review finished with zero findings and the quality gate passed in full (342 tests, all 8 pre-commit hooks, ty and pyright clean, docs build and link check green). --- tasks/detailed_plan.md | 2 +- tasks/tasks.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index f01d87f3..95f6edfd 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -253,7 +253,7 @@ Decisions made before implementation (user-confirmed where noted): policy; `uv run sphinx-build -b linkcheck docs docs/_build/linkcheck` reports no broken links. -### S8: Update the agent skills +### S8: Update the agent skills [done — 21a9333] **Code:** none (documentation-only) **Tests:** skip — no code to test diff --git a/tasks/tasks.md b/tasks/tasks.md index a39098fc..17901159 100644 --- a/tasks/tasks.md +++ b/tasks/tasks.md @@ -36,4 +36,4 @@ - [done] Task 34: Prepare v5.0.0 release (1/2): analyze the code with respect to the issues https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/122 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/76 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/75 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/74 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/28 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/26 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/16 https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/2 and add respective references to the Changelog for the resolved ones. **[USER GUIDANCE]**: "Reference partial, no close claim" (issue #2: only the Zheng & Rugina C alias analysis data is in; the Vedurada 'Batch Alias Analysis' data is missing) / "Reference resolved sub-items only" (umbrella issue #28: cite the resolved sub-issues #27, #32, #20, #30, #33, #26 individually; do not claim #28 done). - [done] Task 35: Prepare v5.0.0 release (2/2): cut the v5.0.0 release per the release skill (bump_version, PR dev->master, tag on origin/master, push, verify PyPI + GitHub Release). **[USER GUIDANCE]**: "Yes, both tasks. But do not forget to ask me to assist with access to PyPI. Guide me step-by-step. And do not forget that I must review and merge requext to master manually, so, tag + push and PyPI/GitHub release only after I confirm that requies merged. Moreover you should pull master irst to create tag on respective commit." / "Trusted publisher added. Go." / "Update all used actions (in GH workflows) to lates versions. Just add commit to this request. Ather that request my assistance again." / "CI report set of warnings of forn ':1: WARNING: py:class reference target not found: networkx.classes.multidigraph.MultiDiGraph [ref.class]' Fix it" / "Well. Can we automatically trigger publishing to testPypi on pr to main to avoid such problems? So, you can check publishing to testPyPi automatically and after that I assist to merge PR." / "I can add trusted publisher for testPypi too. Is it a good way?" / "Is it safe to merge this pr? It will trigger new release that is not requiret (I guess)." - [done] Task 36: Verify that all you experince and knolage on releases are documented. Next release must be fast and smooth. **[USER GUIDANCE]**: "Be carefull. Split global knolage useful for all developers (it must be in docks) and local knolage for you (it must be in skills)" -- [ ] Task 37: Migrate project to UV manager (https://github.com/astral-sh/uv) WE need full migration: no requirements.txt, no other legacy sfuff. Configure project to use UV-provided tools for quality checking: linter, type checker, etc. Do not forget to update documentation. **[USER GUIDANCE]**: "Read https://docs.astral.sh/uv/guides/integration/pre-commit/ can we use official UV pre-commit hooks?" / "Note on ty typechecker. Let use ty for fast check but in CI use both ty and pyright." / "Delete both (Recommended)" (broken legacy scripts utils/fetch_dataset.py and utils/update_dataset_tables.py) +- [done] Task 37: Migrate project to UV manager (https://github.com/astral-sh/uv) WE need full migration: no requirements.txt, no other legacy sfuff. Configure project to use UV-provided tools for quality checking: linter, type checker, etc. Do not forget to update documentation. **[USER GUIDANCE]**: "Read https://docs.astral.sh/uv/guides/integration/pre-commit/ can we use official UV pre-commit hooks?" / "Note on ty typechecker. Let use ty for fast check but in CI use both ty and pyright." / "Delete both (Recommended)" (broken legacy scripts utils/fetch_dataset.py and utils/update_dataset_tables.py) From 26d9929d1360ca6607b2a090e3b8c18d15dfdc8c Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 13:23:00 +0300 Subject: [PATCH 014/277] =?UTF-8?q?fix(37-S9):=20pin=20astral-sh/setup-uv?= =?UTF-8?q?=20to=20v10.1.0=20=E2=80=94=20the=20v10=20tag=20does=20not=20ex?= =?UTF-8?q?ist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first CI run on dev (07b4fb0) failed all four workflows at action resolution: 'Unable to resolve action astral-sh/setup-uv@v10, unable to find version v10'. Unlike actions/checkout, astral-sh/setup-uv publishes only full semver tags (v10.1.0, v10.0.1, ...) — there is no major-only alias, so @v10 can never resolve. Pin all six workflows to v10.1.0 (the current release). Verified: every workflow parses as YAML, and the CI install steps were simulated locally for all three dependency groups (uv sync --frozen --only-group test/docs/dev), with pytest collection, sphinx-build, pre-commit, ruff, ty and pyright all resolving in their group environments. --- .github/workflows/coverage.yml | 2 +- .github/workflows/deploy_docs.yml | 2 +- .github/workflows/docs.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/publish.yml | 2 +- .github/workflows/tests.yml | 2 +- tasks/detailed_plan.md | 15 +++++++++++++++ 7 files changed, 21 insertions(+), 6 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index b2fbef6a..cebb4115 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v7 - name: Set up uv with Python ${{ matrix.python-version }} - uses: astral-sh/setup-uv@v10 + uses: astral-sh/setup-uv@v10.1.0 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/deploy_docs.yml b/.github/workflows/deploy_docs.yml index 216f5971..4074013b 100644 --- a/.github/workflows/deploy_docs.yml +++ b/.github/workflows/deploy_docs.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v7 - name: Set up uv with Python ${{ matrix.python-version }} - uses: astral-sh/setup-uv@v10 + uses: astral-sh/setup-uv@v10.1.0 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index ca151745..87c12ca7 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v7 - name: Set up uv with Python ${{ matrix.python-version }} - uses: astral-sh/setup-uv@v10 + uses: astral-sh/setup-uv@v10.1.0 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index acc24206..1a998ed9 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v7 - name: Set up uv with Python ${{ matrix.python-version }} - uses: astral-sh/setup-uv@v10 + uses: astral-sh/setup-uv@v10.1.0 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1687a0f9..37ab0128 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,7 +18,7 @@ jobs: steps: - uses: actions/checkout@v7 - - uses: astral-sh/setup-uv@v10 + - uses: astral-sh/setup-uv@v10.1.0 with: python-version: '3.11' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 017b1658..f37dedf3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v7 - name: Set up uv with Python ${{ matrix.python-version }} - uses: astral-sh/setup-uv@v10 + uses: astral-sh/setup-uv@v10.1.0 with: python-version: ${{ matrix.python-version }} diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index 95f6edfd..7e440d58 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -275,6 +275,21 @@ Decisions made before implementation (user-confirmed where noted): duplication beyond what the skills already carry. - Verification: grep `.opencode/skills/` for `poetry` → no matches. +### S9: Pin astral-sh/setup-uv to an existing tag + +Added 2026-09-17 after the merge (user: "CI with these changes failed. Fix +it."). The first CI run on `07b4fb0` failed all four workflows at action +resolution — `Unable to resolve action astral-sh/setup-uv@v10, unable to +find version v10`: unlike actions/checkout, the setup-uv repo has no +major-only tag alias (only full semver tags: v10.1.0, v10.0.1, ...). + +**Code:** `.github/workflows/{tests,coverage,docs,deploy_docs,lint,publish}.yml` + — `astral-sh/setup-uv@v10` → `astral-sh/setup-uv@v10.1.0` +**Tests:** every workflow parses as YAML; no `setup-uv@v10` references + remain; the CI `uv sync --frozen --only-group ` commands are + simulated locally for all three groups. +**Docs:** none (the workflows are not described in the docs). + ## Post-subtask steps 1. Code review of the whole task diff (`code-review` skill), iterate to zero From cfb31aced6bea617cf2dc45cf9c5620d92435225 Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 14:33:22 +0300 Subject: [PATCH 015/277] fix(37-S10): install all dependency groups in every CI job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The lint job failed on 26d9929: its 'ty-check' pre-commit hook reported 34 unresolved-import diagnostics (pytest in every test file, sphinx.util in docs/conf.py). Root cause, verified with scratch environments: uv's default group selection installs only the dev group, and '--only-group ' installs only that group — not the main dependencies, not the project, not the other groups. The lint job synced '--only-group dev', so pytest (test group) and sphinx (docs group) were absent; 'uv run' implicit syncs add only project + main deps + the default dev group, never the missing ones. Locally the check passed because the working venv had all groups. The tests job had passed only by accident: its implicit sync happened to install the dev group (boto3), which tests/utils/ imports. Every job now runs 'uv sync --frozen --all-groups': one complete, identical environment everywhere, so no check can fail on an import from a group its job did not install. Verified by simulating each job's exact CI sequence in a fresh environment: ty + pyright clean, 342 tests pass, docs build succeeds. --- .github/workflows/coverage.yml | 7 +++++-- .github/workflows/deploy_docs.yml | 7 +++++-- .github/workflows/docs.yml | 7 +++++-- .github/workflows/lint.yml | 7 +++++-- .github/workflows/tests.yml | 7 +++++-- tasks/detailed_plan.md | 30 ++++++++++++++++++++++++++++++ 6 files changed, 55 insertions(+), 10 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index cebb4115..0ae05cd1 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -16,9 +16,12 @@ jobs: with: python-version: ${{ matrix.python-version }} - # --frozen fails if uv.lock is out of sync with pyproject.toml. + # --frozen fails if uv.lock is out of sync with pyproject.toml; + # --all-groups installs the full environment so every check resolves + # imports from any dependency group (ty/pyright type-check tests/, + # docs/conf.py and utils/, which import pytest, sphinx and boto3). - name: Install dependencies with uv - run: uv sync --frozen --only-group test + run: uv sync --frozen --all-groups - name: Show installed packages run: uv tree diff --git a/.github/workflows/deploy_docs.yml b/.github/workflows/deploy_docs.yml index 4074013b..059d7b43 100644 --- a/.github/workflows/deploy_docs.yml +++ b/.github/workflows/deploy_docs.yml @@ -20,9 +20,12 @@ jobs: with: python-version: ${{ matrix.python-version }} - # --frozen fails if uv.lock is out of sync with pyproject.toml. + # --frozen fails if uv.lock is out of sync with pyproject.toml; + # --all-groups installs the full environment so every check resolves + # imports from any dependency group (ty/pyright type-check tests/, + # docs/conf.py and utils/, which import pytest, sphinx and boto3). - name: Install dependencies with uv - run: uv sync --frozen --only-group docs + run: uv sync --frozen --all-groups - name: Show installed packages run: uv tree diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 87c12ca7..a2ac7d13 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -16,9 +16,12 @@ jobs: with: python-version: ${{ matrix.python-version }} - # --frozen fails if uv.lock is out of sync with pyproject.toml. + # --frozen fails if uv.lock is out of sync with pyproject.toml; + # --all-groups installs the full environment so every check resolves + # imports from any dependency group (ty/pyright type-check tests/, + # docs/conf.py and utils/, which import pytest, sphinx and boto3). - name: Install dependencies with uv - run: uv sync --frozen --only-group docs + run: uv sync --frozen --all-groups - name: Show installed packages run: uv tree diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1a998ed9..c64b0256 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -16,9 +16,12 @@ jobs: with: python-version: ${{ matrix.python-version }} - # --frozen fails if uv.lock is out of sync with pyproject.toml. + # --frozen fails if uv.lock is out of sync with pyproject.toml; + # --all-groups installs the full environment so every check resolves + # imports from any dependency group (ty/pyright type-check tests/, + # docs/conf.py and utils/, which import pytest, sphinx and boto3). - name: Install dependencies with uv - run: uv sync --frozen --only-group dev + run: uv sync --frozen --all-groups - name: Run pre-commit run: | diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f37dedf3..3893503a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -21,9 +21,12 @@ jobs: with: python-version: ${{ matrix.python-version }} - # --frozen fails if uv.lock is out of sync with pyproject.toml. + # --frozen fails if uv.lock is out of sync with pyproject.toml; + # --all-groups installs the full environment so every check resolves + # imports from any dependency group (ty/pyright type-check tests/, + # docs/conf.py and utils/, which import pytest, sphinx and boto3). - name: Install dependencies with uv - run: uv sync --frozen --only-group test + run: uv sync --frozen --all-groups - name: Show installed packages run: uv tree diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index 7e440d58..01e0c866 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -290,6 +290,36 @@ major-only tag alias (only full semver tags: v10.1.0, v10.0.1, ...). simulated locally for all three groups. **Docs:** none (the workflows are not described in the docs). +### S10: Install all dependency groups in every CI job + +Added 2026-09-17 after the merge (user: "CI still failed. ... Fix CI in +feature branch and then move to dev."). The second CI run on `26d9929` +passed tests/coverage/docs but the lint job's `ty-check` hook failed with +34 `unresolved-import` diagnostics: `pytest` in every test file and +`sphinx.util` in `docs/conf.py`. + +Root cause (verified empirically with scratch environments): uv's default +group selection installs only the `dev` group, and `--only-group ` +installs *only* that group — not the main dependencies, not the project, +not the other groups. The lint job synced `--only-group dev`, so its +environment had no pytest (test group) or sphinx (docs group); `uv run`'s +implicit sync adds only project + main deps + the default `dev` group, +never the missing ones. Locally the check passed because the working venv +had all groups. The tests job had passed only by accident: its implicit +sync happened to install the dev group (boto3), which `tests/utils/` +imports. + +**Code:** `.github/workflows/{tests,coverage,docs,deploy_docs,lint}.yml` — + `uv sync --frozen --only-group ` → `uv sync --frozen + --all-groups`: every job gets the same complete environment, so + no check can fail on an import from a group its job did not + install. +**Tests:** each job's exact CI sequence simulated in a scratch environment + (`UV_PROJECT_ENVIRONMENT`): `uv sync --frozen --all-groups` then + `uv run ty check` + `uv run pyright` (lint), `uv run pytest` + (tests), `uv run make -C docs html` (docs). +**Docs:** none. + ## Post-subtask steps 1. Code review of the whole task diff (`code-review` skill), iterate to zero From 3cb5dc3432e64590c09f7432a7e0b054881b19bd Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 15:30:33 +0300 Subject: [PATCH 016/277] docs(38-S1): record task 38 in the task log and write the detailed plan --- tasks/detailed_plan.md | 393 +++++++++-------------------------------- tasks/tasks.md | 1 + 2 files changed, 81 insertions(+), 313 deletions(-) diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index 01e0c866..6236459c 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -1,332 +1,99 @@ -# Task 37: Migrate project to UV manager +# Task 38: Issue-closing commit messages -## Context +Task (verbatim): We use mechanism to close issues automatically described here: https://github.blog/news-insights/product-news/closing-issues-via-commit-messages/ Improve imstructions to write respective commut message when task is link to issue. -The project is managed with **Poetry** (`pyproject.toml` `[tool.poetry]` + -`poetry.lock`) on top of a **legacy setuptools layer**: `setup.py` reads -`requirements/*.txt` (via `MANIFEST.in`) to declare the PyPI distribution, and -all five CI workflows install dependencies through Poetry. Quality checking is -limited to `black` (formatting) via pre-commit; there is no linter and no type -checker. - -The user requires a **full migration to uv** (https://github.com/astral-sh/uv): -no `requirements.txt`, no other legacy stuff, uv-managed quality tools -(linter, type checker), and updated documentation. +Branch: `feature/38-issue-closing-commit-messages` (from `dev`). +Documentation-only task: no `.py` files change; code-specific gates (tests, +lint, format) are skipped per the workflow rules, docs build + link check still apply. ## Decision record -Decisions made before implementation (user-confirmed where noted): - -1. **Package manager**: uv 0.12.x. `uv.lock` is committed (the project has - dependency groups, so a lockfile is required for reproducible dev - environments). `.python-version` = `3.11` (matches the CI matrix and the - `requires-python` floor) and is committed; the `.gitignore` entry that - ignored it is removed. -2. **Project metadata**: PEP 621 `[project]` table in `pyproject.toml`; - build backend **hatchling** (uv's default recommendation). Flat layout, so - `[tool.hatch.build.targets.wheel] packages = ["cfpq_data"]`. Distribution - name is `cfpq-data` (PEP 503-normalized; Poetry used `cfpq_data`). License - uses the PEP 639 SPDX string `"Apache-2.0 AND CC-BY-4.0"` (fall back to - `{ text = ... }` if hatchling rejects it; in that case keep the - `License ::` classifier, otherwise drop it per PEP 639). Classifiers are - carried over from `setup.py`, with the stale `Python :: 3.9` entry replaced - by 3.11/3.12/3.13. -3. **Dependencies**: runtime deps converted from Poetry constraints to PEP 508 - (`^3.6.1` → `>=3.6.1,<4.0.0`; `pyformlang = "1.0.1"` → `==1.0.1`). -4. **Dev dependencies**: PEP 735 `[dependency-groups]`: - - `dev`: `ruff`, `ty`, `pyright`, `pre-commit`, `boto3` - - `test`: `pytest`, `pytest-cov` - - `docs`: the Sphinx stack (`sphinx`, `pydata-sphinx-theme`, `numpydoc`, - `nb2plots`, `sphinx-copybutton`, `ipykernel`, `jupyter-client`) - - Dropped: `codecov` (the pip CLI is unused — CI uploads via - `codecov/codecov-action`), `black` (replaced by `ruff format`). - - The old `setup.py` extras (`developer`, `docs`, `tests`) are dropped: - dev tools as install extras is the legacy anti-pattern; dependency groups - replace them. -5. **Quality tools** (user guidance, verbatim in `tasks/tasks.md`): - - **Linter + formatter**: ruff (lint rules `E,F,W,I`; `ruff format`). - One-time reformat commit. - - **Type checker**: **ty for the fast local check; CI runs both ty and - pyright** (user guidance). - - **pre-commit is kept** as the commit-time runner, using **official hooks** - (user asked for official uv pre-commit hooks): `astral-sh/uv-pre-commit` - (`uv-lock`, keeps `uv.lock` in sync), `astral-sh/ruff-pre-commit` - (`ruff-check --fix`, `ruff-format`; rev pinned to the locked ruff version - — both must be bumped together), the existing hygiene hooks, and local - hooks for the version-sync check and `uv run ty check`. Dropped: the - `black` hook and `requirements-txt-fixer`. -6. **CI**: all workflows use `astral-sh/setup-uv@v10` (with - `python-version: "3.11"`); deps via `uv sync --frozen --only-group `; - commands via `uv run ...`; the publish job builds with `uv build`. The lint - job runs the pre-commit pass plus `uv run ty check` and `uv run pyright`. - `uv sync` installs the project itself (editable), so the separate - `pip install .` steps disappear. -7. **Packaging**: `setup.py`, `MANIFEST.in`, `requirements.txt`, - `requirements/`, `poetry.lock` are deleted. The hatchling sdist includes - VCS-tracked files; `cfpq_data/data` stays out (gitignored, downloaded at - runtime). `uv build` builds the wheel from the source tree (not from the - sdist as `python -m build` did) — the TestPyPI pre-publish still validates - the build and metadata; `docs/release.rst` is rewritten accordingly. -8. **Version sync**: `cfpq_data/config.py` stays canonical; - `utils/check_version_sync.py` and `utils/bump_version.py` work unchanged on - PEP 621 (their `^version = "..."` regex matches `[project] version`). -9. **Broken legacy scripts** (user decision: delete): `utils/fetch_dataset.py` - (imports removed `AWS_*`/`BUCKET_NAME` from `cfpq_data.config`, writes a - non-existent `cfpq_data/dataset.py`) and `utils/update_dataset_tables.py` - (imports non-existent `graph_from_dataset`). Both fail at import time, have - no tests, and are referenced by no docs/skill/README. -10. **Type-check scope**: `cfpq_data`, `tests`, `utils`. Tests import the - `utils/` scripts as top-level modules (via `tests/utils/conftest.py` - sys.path insertion), so both checkers get `extraPaths = ["utils"]`. - -## Probe results (measured on the current code, 2026-09-16) - -- ruff (`E,F,W,I`): 130 findings — 41 F403 (star imports in `__init__.py`), - 36 I001 (unsorted imports, auto-fixable), 35 E501 (line too long), 10 F401, - 4 E402, 2 E741, 1 F405, 1 E714; 46 auto-fixable. 34 files need reformatting. -- ty 0.0.81: 74 diagnostics — most are import resolution (pytest not in the - probe env; `utils` modules), ~10 real errors (regex `.group` on - `Match | None` in `cfpq_data/grammars/converters/cfg.py` ×2 and - `utils/fetch_dataset.py` ×1 [deleted], missing members in the two deleted - scripts, 2× `invalid-argument-type` in tests). -- pyright 1.1.414 (basic mode): 41 errors — 15 reportMissingImports (utils - modules + deleted scripts), 15 reportArgumentType, 7 - reportOptionalMemberAccess, 4 reportAttributeAccessIssue (deleted scripts). - After S2 deletions + `extraPaths`, ~26 real errors remain. +Decisions made before implementation: + +1. **Mechanism** (per the linked GitHub post): GitHub closes an issue when a + commit whose message contains a closing keyword (`close`, `closes`, + `closed`, `fixes`, `fixed`) reaches the repository's **default branch**. + Verified for this repo: the default branch is `master` + (`git ls-remote --symref origin HEAD` -> `refs/heads/master`). +2. **Closing timing**: our flow merges feature branches to `dev`; only a + release merges `dev` -> `master`. Therefore a linked issue closes when the + release containing the task lands on `master`, not when the task merges to + `dev`. This is documented as intended behavior: an issue stays open until + the fix is actually released. +3. **Placement**: exactly one commit of a task carries the closing keyword — + by convention the **first subtask's commit**, as a standalone line in the + message body. Rationale: a branch merges only after ALL subtasks complete, + so placement does not affect correctness; the first commit makes validation + monotonic (0 matches before S1, 1 afterwards) and never requires rewording + when the plan grows. +4. **Keyword choice**: `Fixes #N` when the task fixes a reported defect, + `Closes #N` for all other work. One keyword line per fully resolved issue. +5. **Partial resolution**: reference the issue without a closing keyword (bare + `#N`) — GitHub links it but leaves it open. Consistent with the task 34 + user guidance "Reference partial, no close claim". +6. **Single source of truth**: the model lives in the "Contribution + guidelines" section of `docs/developer.rst` (new "Issue references" + subsection); the `git-workflow` skill gains only the operational validation + and points to the docs. No other skill is touched (`subtask-loop` step 6 + already defers commit rules to `git-workflow`). ## Subtasks -### S1: Record task 37 in the task log and write this detailed plan [done — 2516b06] - -**Code:** none (documentation-only) -**Tests:** skip — no code to test -**Docs:** `tasks/tasks.md` (task 37 line with verbatim user guidance), - `tasks/detailed_plan.md` (this file) - -**Spec:** -- Task line recorded verbatim; all three user-guidance items appended - verbatim (official uv pre-commit hooks; ty fast / ty+pyright in CI; delete - the two broken scripts). - -### S2: Core uv migration — PEP 621 pyproject, lockfile, legacy removal [done — 3f69e99] - -**Code:** Rewrite `pyproject.toml` (PEP 621 `[project]`, - `[dependency-groups]`, hatchling `[build-system]` + - `[tool.hatch.build.targets.wheel] packages = ["cfpq_data"]`, keep - `[tool.pytest.ini_options]`); add `.python-version` (`3.11`); - generate `uv.lock`; delete `poetry.lock`, `setup.py`, - `MANIFEST.in`, `requirements.txt`, `requirements/`, - `utils/fetch_dataset.py`, `utils/update_dataset_tables.py`; - remove the `.python-version` line from `.gitignore`; delete stale - local build artifacts (`build/`, `dist/`, `cfpq_data.egg-info/`). -**Tests:** `uv sync --all-groups` succeeds; `uv run python -c - "import cfpq_data"` works; the full suite is green under uv - (`uv run pytest --doctest-modules -vv -s cfpq_data tests`, 0 - failures); `uv run python utils/check_version_sync.py` exits 0; - `uv build` produces sdist + wheel with correct metadata (name - `cfpq-data`, version, deps, license, readme) and the sdist contains - `cfpq_data/`, `README.rst`, `LICENSE.txt`, `LICENSE-DATA.txt` but no - `cfpq_data/data`. -**Docs:** `CHANGELOG.md` `[Unreleased]`: Changed (uv migration, PEP 621 + - hatchling, dependency groups) and Removed (legacy packaging files, - unused `codecov` dev dep, the two broken scripts). - -**Spec:** -- Dependency ranges per decision 3; groups per decision 4. -- If hatchling rejects the SPDX license string, use `{ text = ... }` and keep - the `License ::` classifier (decision 2 fallback). -- Reuse: `utils/check_version_sync.py` / `utils/bump_version.py` unchanged - (verified compatible with PEP 621). - -### S3: Ruff lint + format config and one-time code pass [done — a3def54] - -**Code:** Add `[tool.ruff]` (`target-version = "py311"`), - `[tool.ruff.lint]` (`select = ["E", "F", "W", "I"]`) and - `[tool.ruff.lint.per-file-ignores]` to `pyproject.toml`; run - `uv run ruff check --fix .` and `uv run ruff format .`; manually fix - the remaining findings (E501 line wraps, E741 ambiguous names, - E714, F405, any F401 that is an intentional re-export). -**Tests:** Full suite green after reformatting (doctests included); - `uv run ruff check .` and `uv run ruff format --check .` are clean. -**Docs:** `CHANGELOG.md` `[Unreleased]` Added: ruff as the lint/format gate. - -**Spec:** -- Per-file ignores (from the probe): `"__init__.py" = ["F403"]` (star imports - are the package's public-API re-export pattern); - `"tests/utils/conftest.py" = ["E402"]` (sys.path insertion must precede the - utils imports). Any other per-file ignore must be justified in the commit - message. -- F401 findings are reviewed one by one: genuinely unused imports are removed; - intentional re-exports keep a `# noqa: F401`. -- `ruff format` must not change doctest output (it does not touch docstrings); - the suite is the guard. - -### S4: Type checking — ty + pyright config and error fixes [done — 5878e10] +### S1: Record task 38 in the task log and write the detailed plan -**Code:** Add `[tool.ty.environment]` (`extra-paths = ["utils"]`) and - `[tool.pyright]` (`pythonVersion = "3.11"`, `extraPaths = ["utils"]`) - to `pyproject.toml`; fix every real ty and pyright error in - `cfpq_data/`, `tests/`, `utils/` (regex `.group` on `Match | None` - needs a None guard; argument-type mismatches are fixed at the call - site or by correcting an over-narrow annotation — whichever matches - the intended behavior). -**Tests:** `uv run ty check` exits 0; `uv run pyright` exits 0; full suite - green. -**Docs:** `CHANGELOG.md` `[Unreleased]` Added: type checking (ty locally, - ty + pyright in CI). +**Code:** N/A (documentation-only task) +**Tests:** Skip — no code to test +**Docs:** `tasks/tasks.md` (append the task line, user wording verbatim), + `tasks/detailed_plan.md` (this plan) **Spec:** -- No `# type: ignore` / `# ty: ignore` suppressions unless a specific false - positive is documented in the commit message with the checker and rule. -- ty's `python-version` is auto-detected from `requires-python` (3.11); set it - explicitly only if detection misbehaves. -- pyright runs in its default `basic` mode; do not lower the mode to get - green — fix or justify. +- Append `- Task 38: ` to `tasks/tasks.md`. +- Replace `tasks/detailed_plan.md` with this plan. -### S5: Rewrite .pre-commit-config.yaml with official hooks [done — 2f34ee3] +### S2: Document the issue-closing commit rules in the developer docs -**Code:** New `.pre-commit-config.yaml`: - - `pre-commit/pre-commit-hooks` v6.0.0: `check-yaml`, - `end-of-file-fixer`, `trailing-whitespace` (drop - `requirements-txt-fixer`) - - `astral-sh/uv-pre-commit` 0.12.15: `uv-lock` - - `astral-sh/ruff-pre-commit` v0.16.7: `ruff-check` - (`args: [--fix]`), `ruff-format` - - local: `check-version-sync` (unchanged entry), `ty-check` - (`entry: uv run ty check`, `language: system`, - `pass_filenames: false`, `files: \.py$`) - Drop the `black` hook. -**Tests:** `uv run pre-commit run --all-files` — every hook passes (including - `uv-lock`, both ruff hooks, and the local ty hook). -**Docs:** `docs/developer.rst`: replace the "Pre-commit" section with a - "Quality checks" section covering the official-hook setup (and the - rule that the `ruff-pre-commit` rev must match the locked ruff - version), the local commands (`uv run ruff check .`, - `uv run ruff format .`, `uv run ty check`), and the fact that CI - additionally runs pyright; update the "Test pipeline" command to - `uv run pytest ...`; add type checking to the "Quality gate" list in - "Contribution guidelines". +**Code:** N/A (documentation-only task) +**Tests:** Skip — no code to test +**Docs:** `docs/developer.rst` — "Contribution guidelines" section, new + "Issue references" subsection right after the "Commits" format text. **Spec:** -- The hook list in `.pre-commit-config.yaml` stays the single source of truth - (docs describe it, never duplicate it). -- `uv run ty check` as a local hook requires uv on PATH — that is now a - project prerequisite (documented in "Development setup"). +- State the mechanism: GitHub closes an issue once a commit containing a + closing keyword (`close`, `closes`, `closed`, `fixes`, `fixed`) reaches the + default branch; link the GitHub blog post as the source. +- Rule 1 (full resolution): exactly one commit of the task carries the + keyword — by convention the first subtask's commit — as a standalone line + in the message body: `Fixes #N` for defects, `Closes #N` otherwise; no other + commit of the task repeats it. Include a short example. +- Rule 2 (partial resolution): bare `#N`, no keyword — linked, not closed. +- Timing note: with the dev -> master release flow, a linked issue closes when + the release lands on `master`, not at merge to `dev`. + +### S3: Add operational validation to the git-workflow skill + +**Code:** N/A (documentation-only task) +**Tests:** Skip — no code to test +**Docs:** `.opencode/skills/git-workflow/SKILL.md` — "Commits" section, extend + the pre-commit validation. -### S6: Migrate all CI workflows to uv [done — 73eb75d] - -**Code:** `.github/workflows/{tests,coverage,docs,deploy_docs,lint,publish}.yml`: - replace `actions/setup-python` + Poetry with - `astral-sh/setup-uv@v10` (`python-version: "3.11"`), - `uv sync --frozen --only-group ` (test/docs/dev per job), and - `uv run ...` commands; drop the `pip install .` steps (uv sync - installs the project editable); publish job builds with `uv build`; - lint job gains `uv run ty check` and `uv run pyright` steps. -**Tests:** Every workflow file parses as YAML (`python3 -c - "import yaml,sys; yaml.safe_load(open(sys.argv[1]))"` per file); no - `poetry`/`setup-python` references remain (grep). Real CI runs on - the next push (after merge — noted in the commit message). -**Docs:** `docs/release.rst`: rewrite the "Two packaging constraints" block — - with PEP 621 + hatchling all build inputs are VCS-tracked, and - `uv build` builds the wheel from the source tree (not from the sdist); - the TestPyPI pre-publish still validates build + metadata. Update the - "Builds the sdist and wheel (`python -m build`)" line to `uv build`. - -**Spec:** -- Keep the existing triggers, matrices, permissions, and comments that are - still true; only the tooling steps change. -- `--frozen` makes CI fail if `uv.lock` is out of sync with `pyproject.toml` - (the `uv-lock` pre-commit hook is the local guard). - -### S7: Update remaining docs and verify the docs build [done — 2c73ab7] - -**Code:** none (documentation-only) -**Tests:** skip — no code to test -**Docs:** `docs/README.md` (Poetry → uv commands); `docs/developer.rst` - "Development setup" section (uv installation, `uv sync --all-groups`, - group semantics — replacing the Poetry/package-mode/setup.py/ - requirements paragraphs); `README.rst` developer section (Poetry → - uv); final consistency pass: grep docs + README for - `poetry|requirements|setup.py|MANIFEST` and fix stragglers. **Spec:** -- Verification: `uv run make -C docs html` exits 0 under the no-warnings - policy; `uv run sphinx-build -b linkcheck docs docs/_build/linkcheck` - reports no broken links. - -### S8: Update the agent skills [done — 21a9333] - -**Code:** none (documentation-only) -**Tests:** skip — no code to test -**Docs:** `.opencode/skills/run-tests/SKILL.md` (`poetry run` → `uv run`; - dependency-group note replaces `requirements/tests.txt`; keep the - bare-pytest pitfall, updated env name); - `.opencode/skills/code-style/SKILL.md` (pointer to the new "Quality - checks" section; ruff/ty via `uv run`; hook list stays in - `.pre-commit-config.yaml`); - `.opencode/skills/quality-gates/SKILL.md` (add the type-check step — - ty locally, CI also runs pyright; update the "Pre-commit" section - reference to "Quality checks"); - `.opencode/skills/release/SKILL.md` (`poetry run pre-commit run - check-version-sync --all-files` → `uv run pre-commit run - check-version-sync --all-files`). +- Add an **Issue-closing validation** paragraph: if the task fully resolves a + linked issue, the first subtask's commit must carry the keyword line and no + later commit of the task may repeat it. +- Verification command on the feature branch: + `git log dev..HEAD --format=%B | grep -cE '^(Fixes|Closes) #[0-9]+$'` — must + print `0` before the first subtask's commit and, afterwards, exactly one + line per fully resolved issue (no more). +- Partially addressed issues use a bare `#N` reference (no keyword). +- Point to the "Contribution guidelines" section of `docs/developer.rst` for + the model and closing timing — the skill stays a thin pointer. + +### S4: Mark task 38 done in the task log + +**Code:** N/A (documentation-only task) +**Tests:** Skip — no code to test +**Docs:** `tasks/tasks.md` — prepend `[done] ` to the task 38 line. **Spec:** -- Skills stay thin pointers to the docs (main principle); no command - duplication beyond what the skills already carry. -- Verification: grep `.opencode/skills/` for `poetry` → no matches. - -### S9: Pin astral-sh/setup-uv to an existing tag - -Added 2026-09-17 after the merge (user: "CI with these changes failed. Fix -it."). The first CI run on `07b4fb0` failed all four workflows at action -resolution — `Unable to resolve action astral-sh/setup-uv@v10, unable to -find version v10`: unlike actions/checkout, the setup-uv repo has no -major-only tag alias (only full semver tags: v10.1.0, v10.0.1, ...). - -**Code:** `.github/workflows/{tests,coverage,docs,deploy_docs,lint,publish}.yml` - — `astral-sh/setup-uv@v10` → `astral-sh/setup-uv@v10.1.0` -**Tests:** every workflow parses as YAML; no `setup-uv@v10` references - remain; the CI `uv sync --frozen --only-group ` commands are - simulated locally for all three groups. -**Docs:** none (the workflows are not described in the docs). - -### S10: Install all dependency groups in every CI job - -Added 2026-09-17 after the merge (user: "CI still failed. ... Fix CI in -feature branch and then move to dev."). The second CI run on `26d9929` -passed tests/coverage/docs but the lint job's `ty-check` hook failed with -34 `unresolved-import` diagnostics: `pytest` in every test file and -`sphinx.util` in `docs/conf.py`. - -Root cause (verified empirically with scratch environments): uv's default -group selection installs only the `dev` group, and `--only-group ` -installs *only* that group — not the main dependencies, not the project, -not the other groups. The lint job synced `--only-group dev`, so its -environment had no pytest (test group) or sphinx (docs group); `uv run`'s -implicit sync adds only project + main deps + the default `dev` group, -never the missing ones. Locally the check passed because the working venv -had all groups. The tests job had passed only by accident: its implicit -sync happened to install the dev group (boto3), which `tests/utils/` -imports. - -**Code:** `.github/workflows/{tests,coverage,docs,deploy_docs,lint}.yml` — - `uv sync --frozen --only-group ` → `uv sync --frozen - --all-groups`: every job gets the same complete environment, so - no check can fail on an import from a group its job did not - install. -**Tests:** each job's exact CI sequence simulated in a scratch environment - (`UV_PROJECT_ENVIRONMENT`): `uv sync --frozen --all-groups` then - `uv run ty check` + `uv run pyright` (lint), `uv run pytest` - (tests), `uv run make -C docs html` (docs). -**Docs:** none. - -## Post-subtask steps - -1. Code review of the whole task diff (`code-review` skill), iterate to zero - findings. -2. Quality gate (`quality-gates` skill): full test suite, full pre-commit - pass, `uv run ty check`, docs build, link check — all must PASS. (CI - additionally runs pyright; it is run locally as well since Node 18 is - available on this machine.) -3. Merge to `dev` (rebase + ff-only), delete the feature branch, mark task 37 - `[done]`. +- Only prepend `[done] ` to the existing line; never rewrite the task + description (user-authored, immutable). diff --git a/tasks/tasks.md b/tasks/tasks.md index 17901159..b98bc5f6 100644 --- a/tasks/tasks.md +++ b/tasks/tasks.md @@ -37,3 +37,4 @@ - [done] Task 35: Prepare v5.0.0 release (2/2): cut the v5.0.0 release per the release skill (bump_version, PR dev->master, tag on origin/master, push, verify PyPI + GitHub Release). **[USER GUIDANCE]**: "Yes, both tasks. But do not forget to ask me to assist with access to PyPI. Guide me step-by-step. And do not forget that I must review and merge requext to master manually, so, tag + push and PyPI/GitHub release only after I confirm that requies merged. Moreover you should pull master irst to create tag on respective commit." / "Trusted publisher added. Go." / "Update all used actions (in GH workflows) to lates versions. Just add commit to this request. Ather that request my assistance again." / "CI report set of warnings of forn ':1: WARNING: py:class reference target not found: networkx.classes.multidigraph.MultiDiGraph [ref.class]' Fix it" / "Well. Can we automatically trigger publishing to testPypi on pr to main to avoid such problems? So, you can check publishing to testPyPi automatically and after that I assist to merge PR." / "I can add trusted publisher for testPypi too. Is it a good way?" / "Is it safe to merge this pr? It will trigger new release that is not requiret (I guess)." - [done] Task 36: Verify that all you experince and knolage on releases are documented. Next release must be fast and smooth. **[USER GUIDANCE]**: "Be carefull. Split global knolage useful for all developers (it must be in docks) and local knolage for you (it must be in skills)" - [done] Task 37: Migrate project to UV manager (https://github.com/astral-sh/uv) WE need full migration: no requirements.txt, no other legacy sfuff. Configure project to use UV-provided tools for quality checking: linter, type checker, etc. Do not forget to update documentation. **[USER GUIDANCE]**: "Read https://docs.astral.sh/uv/guides/integration/pre-commit/ can we use official UV pre-commit hooks?" / "Note on ty typechecker. Let use ty for fast check but in CI use both ty and pyright." / "Delete both (Recommended)" (broken legacy scripts utils/fetch_dataset.py and utils/update_dataset_tables.py) +- Task 38: We use mechanism to close issues automatically described here: https://github.blog/news-insights/product-news/closing-issues-via-commit-messages/ Improve imstructions to write respective commut message when task is link to issue. From 73581a6166488419df32f8316162b2f36d286d5d Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 15:32:34 +0300 Subject: [PATCH 017/277] docs(38-S2): document issue-closing commit message rules in the developer guide GitHub closes an issue when a commit with a closing keyword reaches the default branch (master here), so linked issues close at release time, not at merge to dev. The rule: exactly one commit per task carries the keyword (first subtask's commit, Fixes #N for defects / Closes #N otherwise); partial resolution uses a bare #N reference. --- docs/developer.rst | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/docs/developer.rst b/docs/developer.rst index af0ee367..f551cb0d 100644 --- a/docs/developer.rst +++ b/docs/developer.rst @@ -164,6 +164,32 @@ atomic subtask:: lists are not allowed). Commit messages must explain *why* the change was made, not only what it does. +Issue references +~~~~~~~~~~~~~~~~ + +GitHub closes an issue automatically once a commit containing a closing +keyword (``close``, ``closes``, ``closed``, ``fixes``, ``fixed``) reaches the +repository's default branch (`mechanism +`_). +This project relies on that mechanism: + +- A task that fully resolves a linked GitHub issue carries the closing keyword + in exactly one commit — by convention, the first subtask's commit — as a + standalone line in the message body: ``Fixes #N`` when the task fixes a + reported defect, ``Closes #N`` for all other work. No other commit of the + task repeats the keyword:: + + docs(XXX-S1): record the task and write the detailed plan + + Closes #N + +- A task that only partially addresses an issue references it without a + closing keyword (bare ``#N``); GitHub links the issue but leaves it open. + +Since feature branches merge to ``dev`` and only releases merge ``dev`` into +``master``, the default branch, a linked issue closes when the release +containing the task lands on ``master`` — not when the task merges to ``dev``. + Quality gate ~~~~~~~~~~~~ From 1a0a1962b02a66b74fdbdb93bf5beeccf61da144 Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 15:33:25 +0300 Subject: [PATCH 018/277] docs(38-S3): validate issue-closing keywords in the git workflow skill The model lives in docs/developer.rst; the skill keeps only the operational check: the first subtask's commit carries the Fixes/Closes line and no later commit of the task repeats it (grep over dev..HEAD must stay at one line per fully resolved issue). --- .opencode/skills/git-workflow/SKILL.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.opencode/skills/git-workflow/SKILL.md b/.opencode/skills/git-workflow/SKILL.md index a147870d..9b6c1130 100644 --- a/.opencode/skills/git-workflow/SKILL.md +++ b/.opencode/skills/git-workflow/SKILL.md @@ -19,6 +19,20 @@ forbidden). If the message mentions multiple subtask identifiers, STOP — split the changes into individual commits. One commit per completed atomic subtask. +**Issue-closing validation**: if the task links a GitHub issue that it fully +resolves, the first subtask's commit carries the closing keyword (`Fixes #N` +for defects, `Closes #N` otherwise) as a standalone line in the message body, +and no later commit of the task repeats it. Verify on the feature branch: + +```bash +git log dev..HEAD --format=%B | grep -cE '^(Fixes|Closes) #[0-9]+$' +``` + +must print `0` before the first subtask's commit and, afterwards, exactly one +line per fully resolved issue (no more). A task that only partially addresses +an issue uses a bare `#N` reference (no keyword). The model and closing +timing live in the "Contribution guidelines" section of `docs/developer.rst`. + ### Pre-commit checklist 1. Run commit gate: code-style, all tests, linters. From 6704bc32b4050625103a14a38a9f80c3e049d837 Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 15:34:18 +0300 Subject: [PATCH 019/277] docs(38-S4): mark task 38 done in the task log --- tasks/tasks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/tasks.md b/tasks/tasks.md index b98bc5f6..31a2fdfe 100644 --- a/tasks/tasks.md +++ b/tasks/tasks.md @@ -37,4 +37,4 @@ - [done] Task 35: Prepare v5.0.0 release (2/2): cut the v5.0.0 release per the release skill (bump_version, PR dev->master, tag on origin/master, push, verify PyPI + GitHub Release). **[USER GUIDANCE]**: "Yes, both tasks. But do not forget to ask me to assist with access to PyPI. Guide me step-by-step. And do not forget that I must review and merge requext to master manually, so, tag + push and PyPI/GitHub release only after I confirm that requies merged. Moreover you should pull master irst to create tag on respective commit." / "Trusted publisher added. Go." / "Update all used actions (in GH workflows) to lates versions. Just add commit to this request. Ather that request my assistance again." / "CI report set of warnings of forn ':1: WARNING: py:class reference target not found: networkx.classes.multidigraph.MultiDiGraph [ref.class]' Fix it" / "Well. Can we automatically trigger publishing to testPypi on pr to main to avoid such problems? So, you can check publishing to testPyPi automatically and after that I assist to merge PR." / "I can add trusted publisher for testPypi too. Is it a good way?" / "Is it safe to merge this pr? It will trigger new release that is not requiret (I guess)." - [done] Task 36: Verify that all you experince and knolage on releases are documented. Next release must be fast and smooth. **[USER GUIDANCE]**: "Be carefull. Split global knolage useful for all developers (it must be in docks) and local knolage for you (it must be in skills)" - [done] Task 37: Migrate project to UV manager (https://github.com/astral-sh/uv) WE need full migration: no requirements.txt, no other legacy sfuff. Configure project to use UV-provided tools for quality checking: linter, type checker, etc. Do not forget to update documentation. **[USER GUIDANCE]**: "Read https://docs.astral.sh/uv/guides/integration/pre-commit/ can we use official UV pre-commit hooks?" / "Note on ty typechecker. Let use ty for fast check but in CI use both ty and pyright." / "Delete both (Recommended)" (broken legacy scripts utils/fetch_dataset.py and utils/update_dataset_tables.py) -- Task 38: We use mechanism to close issues automatically described here: https://github.blog/news-insights/product-news/closing-issues-via-commit-messages/ Improve imstructions to write respective commut message when task is link to issue. +- [done] Task 38: We use mechanism to close issues automatically described here: https://github.blog/news-insights/product-news/closing-issues-via-commit-messages/ Improve imstructions to write respective commut message when task is link to issue. From 1b0d23d9655dc9d5a47adf46b50b3a8ec591971d Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 15:56:49 +0300 Subject: [PATCH 020/277] docs(38-S5): check links sequentially to survive Wikipedia rate limiting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The quality-gate link check failed with 403 'Too many requests' on two of the four pre-existing Wikipedia URLs: linkcheck's default parallel worker pool trips Wikipedia's per-IP limit from datacenter networks, while the same URLs answer 200 sequentially (verified with the configured User-Agent). linkcheck_workers = 1 keeps every URL checked in full — only concurrency changes. Also records S1-S4 completion hashes and this subtask in the plan. --- docs/conf.py | 7 +++++++ tasks/detailed_plan.md | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 28339228..5c588888 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -111,6 +111,13 @@ r"https?://dacapobench\.sourceforge\.net.*", ] +# linkcheck: check URLs sequentially. Wikipedia rate-limits parallel requests +# from datacenter IPs with 403 ("Too many requests") even for a descriptive +# User-Agent, while sequential requests pass (verified 2026-09); the default +# worker pool makes the check flaky on such networks. Every URL is still +# checked in full — this only changes the concurrency. +linkcheck_workers = 1 + # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index 6236459c..81ac6c4f 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -39,7 +39,7 @@ Decisions made before implementation: ## Subtasks -### S1: Record task 38 in the task log and write the detailed plan +### S1: Record task 38 in the task log and write the detailed plan [done — 3cb5dc3] **Code:** N/A (documentation-only task) **Tests:** Skip — no code to test @@ -50,7 +50,7 @@ Decisions made before implementation: - Append `- Task 38: ` to `tasks/tasks.md`. - Replace `tasks/detailed_plan.md` with this plan. -### S2: Document the issue-closing commit rules in the developer docs +### S2: Document the issue-closing commit rules in the developer docs [done — 73581a6] **Code:** N/A (documentation-only task) **Tests:** Skip — no code to test @@ -69,7 +69,7 @@ Decisions made before implementation: - Timing note: with the dev -> master release flow, a linked issue closes when the release lands on `master`, not at merge to `dev`. -### S3: Add operational validation to the git-workflow skill +### S3: Add operational validation to the git-workflow skill [done — 1a0a196] **Code:** N/A (documentation-only task) **Tests:** Skip — no code to test @@ -88,7 +88,7 @@ Decisions made before implementation: - Point to the "Contribution guidelines" section of `docs/developer.rst` for the model and closing timing — the skill stays a thin pointer. -### S4: Mark task 38 done in the task log +### S4: Mark task 38 done in the task log [done — 6704bc3] **Code:** N/A (documentation-only task) **Tests:** Skip — no code to test @@ -97,3 +97,29 @@ Decisions made before implementation: **Spec:** - Only prepend `[done] ` to the existing line; never rewrite the task description (user-authored, immutable). + +### S5: Make the link check deterministic on rate-limited networks + +Added 2026-09-17 during the quality gate. The full link check failed with +403 "Too many requests" from `en.wikipedia.org` on two of the four Wikipedia +URLs (pre-existing links in `grammars/data/dyck.rst` and the generated +`cfpq_data.grammars.converters.cfg` page — not introduced by this task). + +Root cause (verified empirically): with the configured descriptive +User-Agent, all four URLs answer 200 when requested **sequentially** +(`curl`, 5 s apart), but linkcheck's default parallel worker pool triggers +Wikipedia's per-IP rate limit from this datacenter network — the same +failure mode already documented in `docs/conf.py` for `dl.acm.org` and +`dacapobench.sourceforge.net`, except there the block is persistent while +here it is concurrency-driven. Retrying with delays did not stabilize the +result (different subsets of the four URLs failed per run). + +**Code:** N/A (documentation-only task) +**Tests:** Skip — no code to test +**Docs:** `docs/conf.py` — add `linkcheck_workers = 1` next to the other + linkcheck settings, with the rationale comment. + +**Spec:** +- Sequential checking is not an ignore: every URL is still checked in full; + only the concurrency changes (the check gets slower, never weaker). +- Re-run the full link check; it must report no broken or timed-out links. From 78e88d1d5f77786f6f2a6b2c9e805dc99b9ef3f3 Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 16:12:22 +0300 Subject: [PATCH 021/277] docs(39-S1): record task 39 in the task log and write the detailed plan Issue #94 (PEP 561 py.typed marker) is still open work: inline annotations from task 37 are not enough, a type checker ignores the inline types of an installed package unless it ships a py.typed marker. The issue's setup.py snippet is obsolete after the uv/hatchling migration (task 37), so the fix is the marker file plus empirical verification that the built wheel and sdist ship it, a regression test, and a developer-docs note. Closes #94 --- tasks/detailed_plan.md | 169 +++++++++++++++++------------------------ tasks/tasks.md | 1 + 2 files changed, 69 insertions(+), 101 deletions(-) diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index 81ac6c4f..0570dec8 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -1,125 +1,92 @@ -# Task 38: Issue-closing commit messages +# Task 39: Add the PEP 561 `py.typed` marker (issue #94) -Task (verbatim): We use mechanism to close issues automatically described here: https://github.blog/news-insights/product-news/closing-issues-via-commit-messages/ Improve imstructions to write respective commut message when task is link to issue. +Task (verbatim): Fix https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/94 -Branch: `feature/38-issue-closing-commit-messages` (from `dev`). -Documentation-only task: no `.py` files change; code-specific gates (tests, -lint, format) are skipped per the workflow rules, docs build + link check still apply. +Branch: `feature/39-py-typed-marker` (from `dev`). ## Decision record Decisions made before implementation: -1. **Mechanism** (per the linked GitHub post): GitHub closes an issue when a - commit whose message contains a closing keyword (`close`, `closes`, - `closed`, `fixes`, `fixed`) reaches the repository's **default branch**. - Verified for this repo: the default branch is `master` - (`git ls-remote --symref origin HEAD` -> `refs/heads/master`). -2. **Closing timing**: our flow merges feature branches to `dev`; only a - release merges `dev` -> `master`. Therefore a linked issue closes when the - release containing the task lands on `master`, not when the task merges to - `dev`. This is documented as intended behavior: an issue stays open until - the fix is actually released. -3. **Placement**: exactly one commit of a task carries the closing keyword — - by convention the **first subtask's commit**, as a standalone line in the - message body. Rationale: a branch merges only after ALL subtasks complete, - so placement does not affect correctness; the first commit makes validation - monotonic (0 matches before S1, 1 afterwards) and never requires rewording - when the plan grows. -4. **Keyword choice**: `Fixes #N` when the task fixes a reported defect, - `Closes #N` for all other work. One keyword line per fully resolved issue. -5. **Partial resolution**: reference the issue without a closing keyword (bare - `#N`) — GitHub links it but leaves it open. Consistent with the task 34 - user guidance "Reference partial, no close claim". -6. **Single source of truth**: the model lives in the "Contribution - guidelines" section of `docs/developer.rst` (new "Issue references" - subsection); the `git-workflow` skill gains only the operational validation - and points to the docs. No other skill is touched (`subtask-loop` step 6 - already defers commit rules to `git-workflow`). +1. **The issue is still open work, not stale.** Issue #94 asks for the PEP 561 + `py.typed` marker. Inline type annotations (added in task 37) are necessary + but not sufficient: per PEP 561, a type checker (mypy, pyright) ignores the + inline types of an *installed* package unless the package ships a + `py.typed` marker file. Without it, downstream users get no type + information from `cfpq_data` at all. +2. **The issue's `setup.py` snippet is obsolete.** Packaging migrated from + Poetry + setuptools to PEP 621 + hatchling in task 37 (no `setup.py` + exists). The fix is therefore: create the marker file and confirm the + hatchling build ships it — no `package_data` configuration needed. +3. **Marker location**: `cfpq_data/py.typed`, empty file, tracked in git. + This is the PEP 561 convention for inline-typed packages (no separate + `.pyi` stubs). +4. **Packaging inclusion (to be verified empirically in S2)**: the hatchling + wheel target `packages = ["cfpq_data"]` includes every VCS-tracked file + under the package directory by default, so a git-tracked `py.typed` is + expected to land in the wheel with no `pyproject.toml` change. The sdist + target's `include = ["cfpq_data", ...]` covers it as well. S2 verifies + both by building and inspecting the artifacts; if the wheel misses the + marker, add an explicit hatchling `force-include`/`artifacts` entry. +5. **Regression guard**: a pytest test asserts the marker exists inside the + installed package (`importlib.resources`), so deleting or untracking the + file fails the suite. The built-wheel check is a one-off verification in + S2 (the published artifact is what the issue is about); the test guards + the source of truth. +6. **Docs**: one sentence in the "Quality checks" section of + `docs/developer.rst` — the section that already documents ty/pyright — + stating that the package ships `py.typed` per PEP 561 so downstream type + checkers use the inline annotations. No new doc page (single source of + truth, no duplication). +7. **Issue closing**: the task fully resolves #94, so the first subtask's + commit carries `Closes #94` as a standalone body line (per the + "Issue references" rules in `docs/developer.rst`). The issue closes when + the release containing this task lands on `master`. ## Subtasks -### S1: Record task 38 in the task log and write the detailed plan [done — 3cb5dc3] +### S1: Record task 39 in the task log and write the detailed plan [ ] -**Code:** N/A (documentation-only task) +**Code:** N/A (documentation-only subtask) **Tests:** Skip — no code to test -**Docs:** `tasks/tasks.md` (append the task line, user wording verbatim), - `tasks/detailed_plan.md` (this plan) +**Docs:** `tasks/tasks.md` (append the task line), `tasks/detailed_plan.md` + (this plan) **Spec:** -- Append `- Task 38: ` to `tasks/tasks.md`. +- Append `- [ ] Task 39: Fix https://github.com/.../issues/94` to + `tasks/tasks.md`. - Replace `tasks/detailed_plan.md` with this plan. +- Commit message body carries the standalone line `Closes #94`. -### S2: Document the issue-closing commit rules in the developer docs [done — 73581a6] +### S2: Add `cfpq_data/py.typed` and verify the built wheel ships it [ ] -**Code:** N/A (documentation-only task) -**Tests:** Skip — no code to test -**Docs:** `docs/developer.rst` — "Contribution guidelines" section, new - "Issue references" subsection right after the "Commits" format text. +**Code:** New empty file `cfpq_data/py.typed` (PEP 561 marker, git-tracked). + No `pyproject.toml` change expected (decision 4); add a hatchling + entry only if the empirical check fails. +**Tests:** New `tests/test_py_typed.py`: assert + `importlib.resources.files("cfpq_data") / "py.typed"` exists — + guards the marker against deletion/untracking in both editable and + real installs. +**Docs:** N/A for this subtask (the developer-docs note is S3). **Spec:** -- State the mechanism: GitHub closes an issue once a commit containing a - closing keyword (`close`, `closes`, `closed`, `fixes`, `fixed`) reaches the - default branch; link the GitHub blog post as the source. -- Rule 1 (full resolution): exactly one commit of the task carries the - keyword — by convention the first subtask's commit — as a standalone line - in the message body: `Fixes #N` for defects, `Closes #N` otherwise; no other - commit of the task repeats it. Include a short example. -- Rule 2 (partial resolution): bare `#N`, no keyword — linked, not closed. -- Timing note: with the dev -> master release flow, a linked issue closes when - the release lands on `master`, not at merge to `dev`. - -### S3: Add operational validation to the git-workflow skill [done — 1a0a196] - -**Code:** N/A (documentation-only task) -**Tests:** Skip — no code to test -**Docs:** `.opencode/skills/git-workflow/SKILL.md` — "Commits" section, extend - the pre-commit validation. - -**Spec:** -- Add an **Issue-closing validation** paragraph: if the task fully resolves a - linked issue, the first subtask's commit must carry the keyword line and no - later commit of the task may repeat it. -- Verification command on the feature branch: - `git log dev..HEAD --format=%B | grep -cE '^(Fixes|Closes) #[0-9]+$'` — must - print `0` before the first subtask's commit and, afterwards, exactly one - line per fully resolved issue (no more). -- Partially addressed issues use a bare `#N` reference (no keyword). -- Point to the "Contribution guidelines" section of `docs/developer.rst` for - the model and closing timing — the skill stays a thin pointer. - -### S4: Mark task 38 done in the task log [done — 6704bc3] - -**Code:** N/A (documentation-only task) -**Tests:** Skip — no code to test -**Docs:** `tasks/tasks.md` — prepend `[done] ` to the task 38 line. - -**Spec:** -- Only prepend `[done] ` to the existing line; never rewrite the task - description (user-authored, immutable). - -### S5: Make the link check deterministic on rate-limited networks - -Added 2026-09-17 during the quality gate. The full link check failed with -403 "Too many requests" from `en.wikipedia.org` on two of the four Wikipedia -URLs (pre-existing links in `grammars/data/dyck.rst` and the generated -`cfpq_data.grammars.converters.cfg` page — not introduced by this task). +- Create the empty `cfpq_data/py.typed` file. +- Add the regression test (style: plain pytest, no fixtures needed). +- Verify empirically: `uv build --wheel` and `uv build --sdist`, then inspect + both artifacts (`unzip -l` / `tar -tzf`) and confirm `cfpq_data/py.typed` + is present in each. Clean up `dist/` afterwards (build output, not source). +- Run the test suite for the new test. -Root cause (verified empirically): with the configured descriptive -User-Agent, all four URLs answer 200 when requested **sequentially** -(`curl`, 5 s apart), but linkcheck's default parallel worker pool triggers -Wikipedia's per-IP rate limit from this datacenter network — the same -failure mode already documented in `docs/conf.py` for `dl.acm.org` and -`dacapobench.sourceforge.net`, except there the block is persistent while -here it is concurrency-driven. Retrying with delays did not stabilize the -result (different subsets of the four URLs failed per run). +### S3: Document the PEP 561 marker in the developer docs [ ] -**Code:** N/A (documentation-only task) +**Code:** N/A (documentation-only subtask) **Tests:** Skip — no code to test -**Docs:** `docs/conf.py` — add `linkcheck_workers = 1` next to the other - linkcheck settings, with the rationale comment. +**Docs:** `docs/developer.rst`, "Quality checks" section — one sentence after + the ty/pyright paragraph: the package ships a PEP 561 `py.typed` + marker, so type checkers in downstream projects use the inline + annotations. **Spec:** -- Sequential checking is not an ignore: every URL is still checked in full; - only the concurrency changes (the check gets slower, never weaker). -- Re-run the full link check; it must report no broken or timed-out links. +- Add the sentence; keep it to the "what/why" (no build instructions — the + packaging config in `pyproject.toml` is the source of truth for "how"). +- Verify the docs build passes under the no-warnings policy. diff --git a/tasks/tasks.md b/tasks/tasks.md index 31a2fdfe..ea8fa5c6 100644 --- a/tasks/tasks.md +++ b/tasks/tasks.md @@ -38,3 +38,4 @@ - [done] Task 36: Verify that all you experince and knolage on releases are documented. Next release must be fast and smooth. **[USER GUIDANCE]**: "Be carefull. Split global knolage useful for all developers (it must be in docks) and local knolage for you (it must be in skills)" - [done] Task 37: Migrate project to UV manager (https://github.com/astral-sh/uv) WE need full migration: no requirements.txt, no other legacy sfuff. Configure project to use UV-provided tools for quality checking: linter, type checker, etc. Do not forget to update documentation. **[USER GUIDANCE]**: "Read https://docs.astral.sh/uv/guides/integration/pre-commit/ can we use official UV pre-commit hooks?" / "Note on ty typechecker. Let use ty for fast check but in CI use both ty and pyright." / "Delete both (Recommended)" (broken legacy scripts utils/fetch_dataset.py and utils/update_dataset_tables.py) - [done] Task 38: We use mechanism to close issues automatically described here: https://github.blog/news-insights/product-news/closing-issues-via-commit-messages/ Improve imstructions to write respective commut message when task is link to issue. +- [ ] Task 39: Fix https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/94 From 7b0cd29a96e9997a35eb056a77cdf60784c518a2 Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 16:13:56 +0300 Subject: [PATCH 022/277] feat(39-S2): ship the PEP 561 py.typed marker in the package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Type checkers (mypy, pyright) ignore the inline annotations of an installed package unless it ships a py.typed marker (PEP 561), so downstream users got no type information from cfpq_data despite the annotations added in task 37. Add the empty marker file; hatchling's wheel target includes every VCS-tracked file under the package directory, so no pyproject.toml change is needed — verified by building both artifacts and inspecting them: the wheel and the sdist both contain cfpq_data/py.typed. The regression test asserts the marker exists in the installed package so deleting or untracking it fails the suite. --- cfpq_data/py.typed | 0 tests/test_py_typed.py | 7 +++++++ 2 files changed, 7 insertions(+) create mode 100644 cfpq_data/py.typed create mode 100644 tests/test_py_typed.py diff --git a/cfpq_data/py.typed b/cfpq_data/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_py_typed.py b/tests/test_py_typed.py new file mode 100644 index 00000000..4b8b8888 --- /dev/null +++ b/tests/test_py_typed.py @@ -0,0 +1,7 @@ +from importlib.resources import files + + +def test_py_typed_marker_present(): + # PEP 561: without the marker, type checkers ignore the inline + # annotations of an installed package. + assert (files("cfpq_data") / "py.typed").is_file() From f2205d4f1604691f49ce08cac3255f9b17577c07 Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 16:14:49 +0300 Subject: [PATCH 023/277] docs(39-S3): document the PEP 561 py.typed marker in the developer guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Quality checks section already explains why ty and pyright run on this repo; add the missing downstream side of the story: because the package ships a PEP 561 py.typed marker, type checkers in downstream projects use the inline annotations instead of treating cfpq_data as untyped. What/why only — the packaging configuration in pyproject.toml remains the source of truth for how the marker is shipped. --- docs/developer.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/developer.rst b/docs/developer.rst index f551cb0d..897304dc 100644 --- a/docs/developer.rst +++ b/docs/developer.rst @@ -69,6 +69,10 @@ CI additionally runs Pyright, the stricter of the two type checkers; ty is the fast local check. The full pass runs on every push and pull request (:file:`.github/workflows/lint.yml`). +The package ships a PEP 561 :file:`py.typed` marker, so type checkers in +downstream projects use the inline annotations of ``cfpq_data`` instead of +treating it as untyped. + .. _developer-tests: Test pipeline From cf7ee09aee8925c5c10b206a62a7faa96261def4 Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 16:17:46 +0300 Subject: [PATCH 024/277] docs(39-S4): mark task 39 done in the task log All subtasks are committed: the py.typed marker ships in both build artifacts (verified by building and inspecting the wheel and sdist), the regression test guards it, and the developer guide documents the PEP 561 marker. Prepend [done] to the task 39 line and record the S1-S3 completion hashes in the plan; this subtask's own entry carries no hash (a commit cannot know its own hash), same convention as task 38's final subtask. --- tasks/detailed_plan.md | 20 +++++++++++++++++--- tasks/tasks.md | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index 0570dec8..3b733046 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -45,7 +45,7 @@ Decisions made before implementation: ## Subtasks -### S1: Record task 39 in the task log and write the detailed plan [ ] +### S1: Record task 39 in the task log and write the detailed plan [done — 78e88d1] **Code:** N/A (documentation-only subtask) **Tests:** Skip — no code to test @@ -58,7 +58,7 @@ Decisions made before implementation: - Replace `tasks/detailed_plan.md` with this plan. - Commit message body carries the standalone line `Closes #94`. -### S2: Add `cfpq_data/py.typed` and verify the built wheel ships it [ ] +### S2: Add `cfpq_data/py.typed` and verify the built wheel ships it [done — 7b0cd29] **Code:** New empty file `cfpq_data/py.typed` (PEP 561 marker, git-tracked). No `pyproject.toml` change expected (decision 4); add a hatchling @@ -77,7 +77,7 @@ Decisions made before implementation: is present in each. Clean up `dist/` afterwards (build output, not source). - Run the test suite for the new test. -### S3: Document the PEP 561 marker in the developer docs [ ] +### S3: Document the PEP 561 marker in the developer docs [done — f2205d4] **Code:** N/A (documentation-only subtask) **Tests:** Skip — no code to test @@ -90,3 +90,17 @@ Decisions made before implementation: - Add the sentence; keep it to the "what/why" (no build instructions — the packaging config in `pyproject.toml` is the source of truth for "how"). - Verify the docs build passes under the no-warnings policy. + +### S4: Mark task 39 done in the task log [ ] + +**Code:** N/A (documentation-only subtask) +**Tests:** Skip — no code to test +**Docs:** `tasks/tasks.md` — prepend `[done] ` to the task 39 line; + `tasks/detailed_plan.md` — record the S1–S3 completion hashes. + +**Spec:** +- Only prepend `[done] ` to the existing task 39 line; never rewrite the task + description (user-authored, immutable). +- Record the S1–S3 completion hashes in this plan (this subtask's own entry + carries no hash — a commit cannot know its own hash; same convention as + task 38's final subtask). diff --git a/tasks/tasks.md b/tasks/tasks.md index ea8fa5c6..9584c4ca 100644 --- a/tasks/tasks.md +++ b/tasks/tasks.md @@ -38,4 +38,4 @@ - [done] Task 36: Verify that all you experince and knolage on releases are documented. Next release must be fast and smooth. **[USER GUIDANCE]**: "Be carefull. Split global knolage useful for all developers (it must be in docks) and local knolage for you (it must be in skills)" - [done] Task 37: Migrate project to UV manager (https://github.com/astral-sh/uv) WE need full migration: no requirements.txt, no other legacy sfuff. Configure project to use UV-provided tools for quality checking: linter, type checker, etc. Do not forget to update documentation. **[USER GUIDANCE]**: "Read https://docs.astral.sh/uv/guides/integration/pre-commit/ can we use official UV pre-commit hooks?" / "Note on ty typechecker. Let use ty for fast check but in CI use both ty and pyright." / "Delete both (Recommended)" (broken legacy scripts utils/fetch_dataset.py and utils/update_dataset_tables.py) - [done] Task 38: We use mechanism to close issues automatically described here: https://github.blog/news-insights/product-news/closing-issues-via-commit-messages/ Improve imstructions to write respective commut message when task is link to issue. -- [ ] Task 39: Fix https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/94 +- [done] Task 39: Fix https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/94 From 4878d044bb8ff90357db0dfb26f6cc0f97e36b57 Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 17:59:30 +0300 Subject: [PATCH 025/277] docs(40-S1): record task 40 in the task log and write the detailed plan Task 40 adds the archive download size to the website graph tables (one Size (MB) column per table, MB chosen as the single unit because all 167 archives span 0.002-112.65 MB), makes utils/upload_to_s3.py report the verified size, and keeps the column maintainable via a new reusable utils/archive_sizes.py tool (check/update against S3). The plan records the live-measured size ranges, the formatting rule, the URL-keying requirement (4.0.0 and 5.0.0 prefixes hold same-named archives with different content), and the decision to keep S3 as the single source of truth instead of adding a repo-side state file. --- tasks/detailed_plan.md | 277 +++++++++++++++++++++++++++-------------- tasks/tasks.md | 1 + 2 files changed, 186 insertions(+), 92 deletions(-) diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index 3b733046..008ae248 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -1,106 +1,199 @@ -# Task 39: Add the PEP 561 `py.typed` marker (issue #94) - -Task (verbatim): Fix https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/94 - -Branch: `feature/39-py-typed-marker` (from `dev`). - -## Decision record - -Decisions made before implementation: - -1. **The issue is still open work, not stale.** Issue #94 asks for the PEP 561 - `py.typed` marker. Inline type annotations (added in task 37) are necessary - but not sufficient: per PEP 561, a type checker (mypy, pyright) ignores the - inline types of an *installed* package unless the package ships a - `py.typed` marker file. Without it, downstream users get no type - information from `cfpq_data` at all. -2. **The issue's `setup.py` snippet is obsolete.** Packaging migrated from - Poetry + setuptools to PEP 621 + hatchling in task 37 (no `setup.py` - exists). The fix is therefore: create the marker file and confirm the - hatchling build ships it — no `package_data` configuration needed. -3. **Marker location**: `cfpq_data/py.typed`, empty file, tracked in git. - This is the PEP 561 convention for inline-typed packages (no separate - `.pyi` stubs). -4. **Packaging inclusion (to be verified empirically in S2)**: the hatchling - wheel target `packages = ["cfpq_data"]` includes every VCS-tracked file - under the package directory by default, so a git-tracked `py.typed` is - expected to land in the wheel with no `pyproject.toml` change. The sdist - target's `include = ["cfpq_data", ...]` covers it as well. S2 verifies - both by building and inspecting the artifacts; if the wheel misses the - marker, add an explicit hatchling `force-include`/`artifacts` entry. -5. **Regression guard**: a pytest test asserts the marker exists inside the - installed package (`importlib.resources`), so deleting or untracking the - file fails the suite. The built-wheel check is a one-off verification in - S2 (the published artifact is what the issue is about); the test guards - the source of truth. -6. **Docs**: one sentence in the "Quality checks" section of - `docs/developer.rst` — the section that already documents ty/pyright — - stating that the package ships `py.typed` per PEP 561 so downstream type - checkers use the inline annotations. No new doc page (single source of - truth, no duplication). -7. **Issue closing**: the task fully resolves #94, so the first subtask's - commit carries `Closes #94` as a standalone body line (per the - "Issue references" rules in `docs/developer.rst`). The issue closes when - the release containing this task lands on `master`. +# Detailed Plan: Task 40 — Archive sizes on the site + upload tool size computation + +## Task + +For the site, add archive sizes (size to download) to tables with graphs. Add +one new column to each table (for each category). Choose one unit of measure +for all graphs (Kb, Mb or Gb). Moreover, improve the tool that uploads a new +graph — it should compute the archive size. When a new graph is added, the +table must be updated; the computed size is used for it. + +**[USER GUIDANCE]**: "Include old graphs (Recommended)" / "Add a reusable +utils script" + +## Decisions (verified against live data, 2026-09-17) + +- **Unit: MB** (decimal, 10^6 bytes), one unit for all graphs. All 167 + archives measured via S3 HEAD (`Content-Length`): + - `5.0.0/graph/` (113 graphs): 2,472 B – 99,645,647 B → 0.002 – 99.65 MB; + - `4.0.0/graph/` (54 old graphs): 2,078 B – 112,652,191 B → 0.002 – 112.65 MB. + KB would reach ~110,000; GB would make every value < 0.12. +- **Formatting rule** (single shared function): `< 1` MB → 3 decimals + (`0.002`, `0.988`); `>= 1` MB → 2 decimals (`1.02`, `57.21`, `99.65`). +- **Column**: header `Size (MB)`, inserted immediately before the existing + `Download` column in every table. +- **Scope**: all 9 graph tables — the 8 per-category pages + (`docs/graphs/{c_alias_analysis,rdf,java_points_to,field_sensitive_alias, + context_sensitive_data_flow,data_provenance,name_resolution, + biological_uniprot}.rst`) and `docs/old_graphs/index.rst`. The benchmarks + table is excluded (it lists benchmark archives, not graphs). Per-graph Info + pages are unchanged. +- **No new state file**: the S3 bucket is the source of truth for archive + sizes. The upload tool reports the size it verifies at upload time; the + table tool fetches the same values from S3. Nothing to keep in sync in the + repo besides the tables themselves. +- **URL keying**: sizes are keyed by full URL, not archive name — the 4.0.0 + and 5.0.0 prefixes contain same-named archives with different content + (old CSV format vs new mtx-per-label format). + +## Reuse analysis (reusing skill) + +- `utils/config.py:MAIN_FOLDER` — reused to anchor the docs paths so the tool + runs from any CWD. +- `utils/audit_info_tables.py` — line-based RST list-table parsing style and + module layout (docstring + usage, `__all__`, pure functions with numpydoc + docstrings, `main(argv)` with argparse) reused as the template for + `archive_sizes.py`. +- `tests/utils/conftest.py` already puts `utils/` on `sys.path`; new tests + follow `tests/utils/test_upload_to_s3.py` conventions (mocked clients, no + network in the test suite). +- `upload_file()` in `utils/upload_to_s3.py` already computes and verifies + the stored size (`head_object` vs local stat) — S5 only surfaces it. +- No existing size-formatting code anywhere (searched `cfpq_data/`, + `utils/`, `docs/`) — `utils/sizes.py` is genuinely new. ## Subtasks -### S1: Record task 39 in the task log and write the detailed plan [done — 78e88d1] +### S1: Record task, create branch, write this plan -**Code:** N/A (documentation-only subtask) -**Tests:** Skip — no code to test -**Docs:** `tasks/tasks.md` (append the task line), `tasks/detailed_plan.md` - (this plan) +**Code:** none. +**Tests:** none. +**Docs:** `tasks/tasks.md` (task line), `tasks/detailed_plan.md` (this file). **Spec:** -- Append `- [ ] Task 39: Fix https://github.com/.../issues/94` to - `tasks/tasks.md`. -- Replace `tasks/detailed_plan.md` with this plan. -- Commit message body carries the standalone line `Closes #94`. - -### S2: Add `cfpq_data/py.typed` and verify the built wheel ships it [done — 7b0cd29] - -**Code:** New empty file `cfpq_data/py.typed` (PEP 561 marker, git-tracked). - No `pyproject.toml` change expected (decision 4); add a hatchling - entry only if the empirical check fails. -**Tests:** New `tests/test_py_typed.py`: assert - `importlib.resources.files("cfpq_data") / "py.typed"` exists — - guards the marker against deletion/untracking in both editable and - real installs. -**Docs:** N/A for this subtask (the developer-docs note is S3). +- Task 40 logged in `tasks/tasks.md` with the user's description verbatim and + the two Q&A decisions as **[USER GUIDANCE]**. +- Feature branch `feature/40-archive-sizes` created from `dev`. + +### S2: Shared size formatting — `utils/sizes.py` + +**Code:** New `utils/sizes.py` with `format_size_mb(size_bytes: int) -> str` +implementing the formatting rule above (decimal MB; 3 decimals below 1, 2 +decimals from 1 up). numpydoc docstring with doctest-stable `Examples`. +**Tests:** New `tests/utils/test_sizes.py`: boundary values (0 B, 999,999 B → +`0.999`, 1,000,000 B → `1.00`, 1,021,000 B → `1.02`), real archive sizes +(wc 2,472 B → `0.002`; taxonomy_hierarchy 112,652,191 B → `112.65`), and the +doctest examples. +**Docs:** none (maintainer-internal module; documented where used in S3/S5). + +**Spec:** +- Pure function, no I/O, no dependencies; importable as top-level `sizes` + (conftest puts `utils/` on `sys.path`). +- The formatting rule lives here and ONLY here — both `archive_sizes.py` and + `upload_to_s3.py` import it (single source of truth). + +### S3: Table tool — `utils/archive_sizes.py` + +**Code:** New `utils/archive_sizes.py`: +- `iter_graph_tables(text: str) -> list[GraphTable]` — line-based parser for + RST `list-table`s whose header row contains a `Download` cell; returns the + table's rows (each row = list of `(line_index, cell_text)` pairs) so both + check and update can operate on it. Tables without a `Download` header are + skipped (e.g. the Contents table in `docs/graphs/index.rst`). +- `extract_url(cell: str) -> str | None` — pulls the `https://…` target out of + a `` `name.tar.gz `_ 📥 `` cell. +- `fetch_sizes(urls: Iterable[str], timeout: float = 30.0, workers: int = 8) + -> dict[str, int]` — HEAD each unique URL (stdlib `urllib.request`, + `ThreadPoolExecutor`), one retry per URL, returns `{url: content_length}`; + raises `RuntimeError` listing the failed URLs so updates are all-or-nothing. +- `update_table(text: str, sizes: dict[str, int]) -> tuple[str, int]` — + rewrites every graph table in the text: inserts a `Size (MB)` header cell + before `Download` where missing and fills/fixes each row's size cell with + `format_size_mb`; returns the new text and the number of changed rows. +- `main(argv) -> int` — default **check mode**: parse + `docs/graphs/*.rst` + `docs/old_graphs/index.rst` (anchored at + `utils.config.MAIN_FOLDER`), fetch sizes, report every row whose cell + disagrees with the stored object (or is missing), exit code 1 on any + problem; `--update`: fetch all sizes first, then rewrite the files and + print what changed. + +**Tests:** New `tests/utils/test_archive_sizes.py` — synthetic RST strings +only, no network: parser finds graph tables and skips non-graph tables; +`extract_url`; `update_table` inserts the column into a table that lacks it +and fixes wrong values in one that has it (idempotent second pass → 0 +changes); row/URL alignment on a multi-grammar table (3 grammar columns, like +`rdf.rst`). `fetch_sizes` tested with a local `http.server` serving HEAD +responses (or monkeypatched `_head_size`) — no external network. +**Docs:** none yet (the tool's docs page section lands in S6, together with +the populated tables it documents). + +**Spec:** +- RST cell insertion preserves the exact indentation of the file + (` * - ` row starts, ` - ` continuation cells); the no-warnings docs + build is the safety net for malformed tables. +- Check mode output: one line per problem + (`:: : table says X, stored is Y`), then a summary; + exit 0 only when every row of every graph table matches S3. +- Update mode writes a file only if it changed; all fetches happen before any + write (a failed HEAD aborts the run with nothing written). + +### S4: Populate the Size (MB) column in all 9 tables + +**Code:** none (the change is produced by running the new tool — dogfooding). +**Tests:** `python utils/archive_sizes.py` (check mode) must report all 9 +tables in sync (167 rows) against live S3. +**Docs:** The 8 per-category tables + `docs/old_graphs/index.rst` gain the +`Size (MB)` column; one sentence added to the "Contents" section of +`docs/graphs/index.rst` describing the column (the download size of the +`.tar.gz` archive, in MB). + +**Spec:** +- Run `python utils/archive_sizes.py --update` from the repo root; inspect + the diff: exactly one new header cell and one new cell per row in each of + the 9 tables, values matching the live S3 sizes fetched during planning. +- Re-run check mode → clean. Build the docs (no-warnings) to validate the + RST. + +### S5: Upload tool reports the computed size + +**Code:** `utils/upload_to_s3.py`: +- `upload_file()` — extend the existing `logging.info` with the verified size + in bytes; return type unchanged (`key`), so `migrate_gdrive_to_s3.py` is + untouched. +- `main()` — print the size in both units using `sizes.format_size_mb`: + `Uploaded FILE to s3://BUCKET/KEY (12345678 bytes, 11.79 MB)`. +**Tests:** Extend `tests/utils/test_upload_to_s3.py`: `test_main_uploads_file` +asserts the byte count and the formatted MB value in the output; a small-file +case exercises the `< 1 MB` formatting branch (`0.000 MB`). +**Docs:** `docs/utils.rst`, "Upload to Yandex S3" section — extend the +verification paragraph: the tool reports the verified size (bytes and MB), +which is the value for the `Size (MB)` column of the graph tables. **Spec:** -- Create the empty `cfpq_data/py.typed` file. -- Add the regression test (style: plain pytest, no fixtures needed). -- Verify empirically: `uv build --wheel` and `uv build --sdist`, then inspect - both artifacts (`unzip -l` / `tar -tzf`) and confirm `cfpq_data/py.typed` - is present in each. Clean up `dist/` afterwards (build output, not source). -- Run the test suite for the new test. - -### S3: Document the PEP 561 marker in the developer docs [done — f2205d4] - -**Code:** N/A (documentation-only subtask) -**Tests:** Skip — no code to test -**Docs:** `docs/developer.rst`, "Quality checks" section — one sentence after - the ty/pyright paragraph: the package ships a PEP 561 `py.typed` - marker, so type checkers in downstream projects use the inline - annotations. +- The reported size is the *verified* stored size (the `head_object` + `ContentLength` that already must equal the local file size) — the same + number `archive_sizes.py` reads back from S3, so a new-graph row filled + from the upload output always matches check mode. + +### S6: Document the tool and the new-graph flow + +**Code:** none. +**Tests:** none (docs-only; docs build in S7). +**Docs:** +- `docs/utils.rst` — new "Archive sizes" section for `utils/archive_sizes.py` + (usage, check vs `--update`, what it covers: the 9 graph tables, URL keying, + all-or-nothing updates), placed after "Upload to Yandex S3". +- `.opencode/skills/add-graph/SKILL.md` — Documentation section gains the size + step: the upload tool reports the archive size; add the category-table row + with that `Size (MB)` value; run `python utils/archive_sizes.py --update` + before committing so every table row (including the new one) matches S3. +- `CHANGELOG.md` `[Unreleased] → Added`: one bullet for the `Size (MB)` column + in the website graph tables, one for the tooling (`upload_to_s3.py` reports + the verified size; new `utils/archive_sizes.py` keeps the column in sync). **Spec:** -- Add the sentence; keep it to the "what/why" (no build instructions — the - packaging config in `pyproject.toml` is the source of truth for "how"). -- Verify the docs build passes under the no-warnings policy. +- The skill stays a thin pointer: it names the step and the command, the + model (column semantics, formatting rule) lives in the docs. -### S4: Mark task 39 done in the task log [ ] +### S7: Quality gate, review, merge -**Code:** N/A (documentation-only subtask) -**Tests:** Skip — no code to test -**Docs:** `tasks/tasks.md` — prepend `[done] ` to the task 39 line; - `tasks/detailed_plan.md` — record the S1–S3 completion hashes. +**Code:** none (fixes only if the gate finds problems). +**Tests:** full quality gate per the `quality-gates` skill: `uv run pytest`, +ruff (check + format), `uv run ty check`, no-warnings docs build, linkcheck. +**Docs:** `tasks/tasks.md` — mark Task 40 `[done]` after the merge. **Spec:** -- Only prepend `[done] ` to the existing task 39 line; never rewrite the task - description (user-authored, immutable). -- Record the S1–S3 completion hashes in this plan (this subtask's own entry - carries no hash — a commit cannot know its own hash; same convention as - task 38's final subtask). +- Whole-repo code review per the `code-review` skill first; iterate to zero + findings. +- Rebase onto `dev`, fast-forward merge, delete the feature branch (per + `git-workflow`). No pushes. diff --git a/tasks/tasks.md b/tasks/tasks.md index 9584c4ca..80f35e28 100644 --- a/tasks/tasks.md +++ b/tasks/tasks.md @@ -39,3 +39,4 @@ - [done] Task 37: Migrate project to UV manager (https://github.com/astral-sh/uv) WE need full migration: no requirements.txt, no other legacy sfuff. Configure project to use UV-provided tools for quality checking: linter, type checker, etc. Do not forget to update documentation. **[USER GUIDANCE]**: "Read https://docs.astral.sh/uv/guides/integration/pre-commit/ can we use official UV pre-commit hooks?" / "Note on ty typechecker. Let use ty for fast check but in CI use both ty and pyright." / "Delete both (Recommended)" (broken legacy scripts utils/fetch_dataset.py and utils/update_dataset_tables.py) - [done] Task 38: We use mechanism to close issues automatically described here: https://github.blog/news-insights/product-news/closing-issues-via-commit-messages/ Improve imstructions to write respective commut message when task is link to issue. - [done] Task 39: Fix https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/94 +- [ ] Task 40: For the site, add archive sizes (size to download) to tables with graphs. Add one new column to each table (for each category). Choose one unit of neasure for all graphs (Kb, Mb or Gb). Moreover, improve tool that uploads new graph. It should compute archive size. When new raph added, table must be updated. So computed size used for it. **[USER GUIDANCE]**: "Include old graphs (Recommended)" / "Add a reusable utils script" From d1eade5b04f3b008c67204a05418660bd7060c33 Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 18:02:09 +0300 Subject: [PATCH 026/277] feat(40-S2): add shared archive size formatting (utils/sizes.py) The Size (MB) column of the website graph tables and the size reported by the upload tool must use one identical formatting rule, so it lives in a single shared module instead of being duplicated. MB (10**6 bytes) is the unit for all graphs: the 167 dataset archives span 0.002-112.65 MB, a range KB (up to ~110,000) and GB (all < 0.12) cannot scale to. Values below one megabyte keep three decimals so small archives do not round to zero; values from one megabyte up keep two. --- tests/utils/test_sizes.py | 26 ++++++++++++++++++++++++++ utils/sizes.py | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 tests/utils/test_sizes.py create mode 100644 utils/sizes.py diff --git a/tests/utils/test_sizes.py b/tests/utils/test_sizes.py new file mode 100644 index 00000000..7fdcce4d --- /dev/null +++ b/tests/utils/test_sizes.py @@ -0,0 +1,26 @@ +from sizes import format_size_mb + + +def test_format_size_mb_below_one_megabyte_uses_three_decimals(): + assert format_size_mb(2472) == "0.002" + assert format_size_mb(988000) == "0.988" + assert format_size_mb(123456) == "0.123" + + +def test_format_size_mb_at_and_above_one_megabyte_uses_two_decimals(): + # 999,999 B is below one megabyte but rounds to 1.000 at three decimals. + assert format_size_mb(999999) == "1.000" + assert format_size_mb(1_000_000) == "1.00" + assert format_size_mb(1_021_000) == "1.02" + assert format_size_mb(59_987_425) == "59.99" + + +def test_format_size_mb_real_archive_sizes(): + # wc.tar.gz (5.0.0) and taxonomy_hierarchy.tar.gz (4.0.0), the smallest + # and largest archives of the dataset. + assert format_size_mb(2472) == "0.002" + assert format_size_mb(112_652_191) == "112.65" + + +def test_format_size_mb_zero(): + assert format_size_mb(0) == "0.000" diff --git a/utils/sizes.py b/utils/sizes.py new file mode 100644 index 00000000..4080d5e5 --- /dev/null +++ b/utils/sizes.py @@ -0,0 +1,39 @@ +"""Archive size formatting shared by the dataset maintainer tools.""" + +__all__ = [ + "format_size_mb", +] + + +def format_size_mb(size_bytes: int) -> str: + """Format an archive size in megabytes for the docs graph tables. + + One unit (MB, 10**6 bytes) is used for every graph. Values below one + megabyte keep three decimals so that small archives do not round to + zero; values from one megabyte up keep two. + + Parameters + ---------- + size_bytes : int + The archive size in bytes. + + Examples + -------- + >>> format_size_mb(2472) + '0.002' + >>> format_size_mb(988000) + '0.988' + >>> format_size_mb(1021000) + '1.02' + >>> format_size_mb(99645647) + '99.65' + + Returns + ------- + size : str + The size in MB: three decimals below 1, two decimals from 1 up. + """ + mb = size_bytes / 1_000_000 + if mb < 1: + return f"{mb:.3f}" + return f"{mb:.2f}" From 51922ffdf230af966d84e6ebc0c1810f14b6dd94 Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 18:34:08 +0300 Subject: [PATCH 027/277] feat(40-S3): add utils/archive_sizes.py to keep the Size (MB) column in sync The website graph tables need a Size (MB) column that stays accurate when archives are re-uploaded, so a reusable tool is required (user decision). It parses every list-table with a Download column in docs/graphs/*.rst and docs/old_graphs/index.rst, HEADs each referenced archive on Yandex S3, and either reports drifted rows (check mode, exit 1) or rewrites the tables (--update, all-or-nothing: every size is fetched before any file is written). Sizes are keyed by full URL because the 4.0.0 and 5.0.0 prefixes hold same-named archives with different content. The parser must keep empty cells (bare '-' lines for non-applicable grammars in rdf.rst) aligned, which a first version got wrong; a regression test pins it. Formatting reuses sizes.format_size_mb so the tool and the upload tool always agree on the rendered value. --- tests/utils/test_archive_sizes.py | 315 ++++++++++++++++++++++ utils/archive_sizes.py | 429 ++++++++++++++++++++++++++++++ 2 files changed, 744 insertions(+) create mode 100644 tests/utils/test_archive_sizes.py create mode 100644 utils/archive_sizes.py diff --git a/tests/utils/test_archive_sizes.py b/tests/utils/test_archive_sizes.py new file mode 100644 index 00000000..7cc5abbd --- /dev/null +++ b/tests/utils/test_archive_sizes.py @@ -0,0 +1,315 @@ +import threading +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer + +import pytest +from archive_sizes import ( + extract_url, + fetch_sizes, + iter_graph_tables, + update_table, +) + +WC_URL = "https://cfpq-data.storage.yandexcloud.net/5.0.0/graph/wc.tar.gz" +BZIP_URL = "https://cfpq-data.storage.yandexcloud.net/5.0.0/graph/bzip.tar.gz" + +TABLE_WITHOUT_SIZE = ( + ".. list-table::\n" + " :header-rows: 1\n" + "\n" + " * - Graph\n" + " - Num Nodes\n" + " - Download\n" + f" * - :ref:`wc`\n" + " - 332\n" + f" - `wc.tar.gz <{WC_URL}>`_ 📥\n" + f" * - :ref:`bzip`\n" + " - 632\n" + f" - `bzip.tar.gz <{BZIP_URL}>`_ 📥\n" +) + +SIZES = {WC_URL: 2472, BZIP_URL: 3601} + + +def test_iter_graph_tables_parses_rows_and_cells(): + tables = iter_graph_tables(TABLE_WITHOUT_SIZE) + + assert len(tables) == 1 + table = tables[0] + assert [cell for _, cell in table.rows[0]] == ["Graph", "Num Nodes", "Download"] + assert [cell for _, cell in table.rows[1]] == [ + ":ref:`wc`", + "332", + f"`wc.tar.gz <{WC_URL}>`_ 📥", + ] + # Cell line indices point at the right lines of the source. + for line_index, _ in table.rows[1]: + assert ( + TABLE_WITHOUT_SIZE.splitlines()[line_index] + .lstrip() + .startswith(("* -", "- ")) + ) + + +def test_iter_graph_tables_keeps_empty_cells_aligned(): + # rdf.rst rows have a bare ``-`` line for grammars that do not apply. + text = ( + ".. list-table::\n" + " :header-rows: 1\n" + "\n" + " * - Graph\n" + " - subClassOf\n" + " - broaderTransitive\n" + " - Download\n" + f" * - :ref:`skos`\n" + " - 1\n" + " -\n" + f" - `skos.tar.gz <{WC_URL}>`_ 📥\n" + ) + + table = iter_graph_tables(text)[0] + + assert [cell for _, cell in table.rows[1]] == [ + ":ref:`skos`", + "1", + "", + f"`skos.tar.gz <{WC_URL}>`_ 📥", + ] + + +def test_iter_graph_tables_skips_tables_without_download_column(): + text = ( + ".. list-table::\n" + " :header-rows: 1\n" + "\n" + " * - Source area\n" + " - Number of graphs\n" + " * - rdf\n" + " - 20\n" + ) + + assert iter_graph_tables(text) == [] + + +def test_extract_url(): + assert extract_url(f"`wc.tar.gz <{WC_URL}>`_ 📥") == WC_URL + assert extract_url("no link here") is None + + +def test_update_table_inserts_missing_size_column(): + updated, changed = update_table(TABLE_WITHOUT_SIZE, SIZES) + + assert changed == 2 + # Re-parse the result: the column sits right before Download in every row. + table = iter_graph_tables(updated)[0] + assert [cell for _, cell in table.rows[0]] == [ + "Graph", + "Num Nodes", + "Size (MB)", + "Download", + ] + assert [cell for _, cell in table.rows[1]] == [ + ":ref:`wc`", + "332", + "0.002", + f"`wc.tar.gz <{WC_URL}>`_ 📥", + ] + assert [cell for _, cell in table.rows[2]] == [ + ":ref:`bzip`", + "632", + "0.004", + f"`bzip.tar.gz <{BZIP_URL}>`_ 📥", + ] + + +def test_update_table_is_idempotent(): + updated, _ = update_table(TABLE_WITHOUT_SIZE, SIZES) + + again, changed = update_table(updated, SIZES) + + assert changed == 0 + assert again == updated + + +def test_update_table_fixes_wrong_values_in_place(): + wrong = ( + ".. list-table::\n" + " :header-rows: 1\n" + "\n" + " * - Graph\n" + " - Num Nodes\n" + " - Size (MB)\n" + " - Download\n" + f" * - :ref:`wc`\n" + " - 332\n" + " - 9.99\n" + f" - `wc.tar.gz <{WC_URL}>`_ 📥\n" + f" * - :ref:`bzip`\n" + " - 632\n" + " - 0.004\n" + f" - `bzip.tar.gz <{BZIP_URL}>`_ 📥\n" + ) + + updated, changed = update_table(wrong, SIZES) + + assert changed == 1 # only the wc row was wrong + table = iter_graph_tables(updated)[0] + assert [cell for _, cell in table.rows[1]] == [ + ":ref:`wc`", + "332", + "0.002", + f"`wc.tar.gz <{WC_URL}>`_ 📥", + ] + # The already-correct bzip row is untouched. + assert [cell for _, cell in table.rows[2]] == [ + ":ref:`bzip`", + "632", + "0.004", + f"`bzip.tar.gz <{BZIP_URL}>`_ 📥", + ] + + +def test_update_table_multi_grammar_column_alignment(): + text = ( + ".. list-table::\n" + " :header-rows: 1\n" + "\n" + " * - Graph\n" + " - Num Nodes\n" + " - subClassOf\n" + " - subClassOf_type\n" + " - type\n" + " - Download\n" + f" * - :ref:`skos`\n" + " - 144\n" + " - 1\n" + " - 30\n" + " - 29\n" + f" - `skos.tar.gz <{WC_URL}>`_ 📥\n" + ) + + updated, changed = update_table(text, SIZES) + + assert changed == 1 + table = iter_graph_tables(updated)[0] + assert [cell for _, cell in table.rows[0]] == [ + "Graph", + "Num Nodes", + "subClassOf", + "subClassOf_type", + "type", + "Size (MB)", + "Download", + ] + + +def test_update_table_with_empty_cells(): + text = ( + ".. list-table::\n" + " :header-rows: 1\n" + "\n" + " * - Graph\n" + " - subClassOf\n" + " - broaderTransitive\n" + " - Download\n" + f" * - :ref:`skos`\n" + " - 1\n" + " -\n" + f" - `skos.tar.gz <{WC_URL}>`_ 📥\n" + ) + + updated, changed = update_table(text, SIZES) + + assert changed == 1 + table = iter_graph_tables(updated)[0] + assert [cell for _, cell in table.rows[0]] == [ + "Graph", + "subClassOf", + "broaderTransitive", + "Size (MB)", + "Download", + ] + assert [cell for _, cell in table.rows[1]] == [ + ":ref:`skos`", + "1", + "", + "0.002", + f"`skos.tar.gz <{WC_URL}>`_ 📥", + ] + + +def test_update_table_leaves_non_graph_tables_untouched(): + text = ( + ".. list-table::\n" + " :header-rows: 1\n" + "\n" + " * - Source area\n" + " - Number of graphs\n" + " * - rdf\n" + " - 20\n" + ) + + updated, changed = update_table(text, SIZES) + + assert changed == 0 + assert updated == text + + +def test_update_table_preserves_trailing_newline(): + no_trailing = TABLE_WITHOUT_SIZE.rstrip("\n") + + updated, _ = update_table(no_trailing, SIZES) + + assert not updated.endswith("\n") + + updated, _ = update_table(TABLE_WITHOUT_SIZE, SIZES) + + assert updated.endswith("\n") + assert not updated.endswith("\n\n") + + +class _HeadHandler(BaseHTTPRequestHandler): + sizes: dict[str, int] = {} + + def do_HEAD(self): + size = self.sizes.get(self.path) + if size is None: + self.send_response(404) + self.end_headers() + return + self.send_response(200) + self.send_header("Content-Length", str(size)) + self.end_headers() + + def log_message(self, format: str, *args: object) -> None: + pass + + +@pytest.fixture() +def head_server(): + server = ThreadingHTTPServer(("127.0.0.1", 0), _HeadHandler) + thread = threading.Thread(target=server.serve_forever, daemon=True) + thread.start() + yield server + server.shutdown() + server.server_close() + + +def test_fetch_sizes_returns_content_lengths(head_server): + base = f"http://127.0.0.1:{head_server.server_address[1]}" + _HeadHandler.sizes = {"/a.tar.gz": 100, "/b.tar.gz": 2_000_000} + + sizes = fetch_sizes([f"{base}/a.tar.gz", f"{base}/b.tar.gz", f"{base}/a.tar.gz"]) + + assert sizes == {f"{base}/a.tar.gz": 100, f"{base}/b.tar.gz": 2_000_000} + + +def test_fetch_sizes_empty_input(head_server): + assert fetch_sizes([]) == {} + + +def test_fetch_sizes_raises_when_object_is_missing(head_server): + base = f"http://127.0.0.1:{head_server.server_address[1]}" + _HeadHandler.sizes = {} + + with pytest.raises(RuntimeError, match="could not fetch the stored size"): + fetch_sizes([f"{base}/nope.tar.gz"]) diff --git a/utils/archive_sizes.py b/utils/archive_sizes.py new file mode 100644 index 00000000..293a3fbf --- /dev/null +++ b/utils/archive_sizes.py @@ -0,0 +1,429 @@ +"""Keep the Size (MB) column of the docs graph tables in sync with S3. + +Every per-category graph table (and the old-graphs table) has a ``Download`` +column linking to the archive on Yandex Object Storage. This tool keeps the +``Size (MB)`` column next to it accurate: + +- check mode (default): HEAD every referenced archive and report the rows + whose size cell disagrees with the stored object; +- ``--update``: fetch all sizes first, then rewrite the tables (inserting + the column where it is missing). + +Sizes are keyed by full URL: the ``4.0.0`` and ``5.0.0`` prefixes hold +same-named archives with different content. + +Usage (from any directory):: + + python utils/archive_sizes.py [--update] +""" + +import argparse +import re +import urllib.request +from concurrent.futures import ThreadPoolExecutor, as_completed +from dataclasses import dataclass +from typing import Iterable, Optional, Sequence + +from config import MAIN_FOLDER +from sizes import format_size_mb + +__all__ = [ + "SIZE_COLUMN", + "GRAPH_TABLE_FILES", + "GraphTable", + "iter_graph_tables", + "extract_url", + "fetch_sizes", + "update_table", + "main", +] + +#: The header cell of the size column in the graph tables. +SIZE_COLUMN = "Size (MB)" + +#: The download-column header every graph table must have to be processed. +DOWNLOAD_COLUMN = "Download" + +#: The docs files holding graph tables, relative to the repository root. +GRAPH_TABLE_FILES: tuple[str, ...] = ( + "graphs/*.rst", + "old_graphs/index.rst", +) + +_ROW_RE = re.compile(r"^(\s+)\* - (.*)$") +# The space after the dash is optional: empty cells are bare ``-`` lines. +_CELL_RE = re.compile(r"^(\s+)- ?(.*)$") +_URL_RE = re.compile(r"<(https?://[^>]+)>") + + +@dataclass +class GraphTable: + """A ``list-table`` with a ``Download`` column. + + Attributes + ---------- + start_line : int + The 0-based index of the ``.. list-table::`` line in the file text. + rows : list[list[tuple[int, str]]] + The table rows in order; ``rows[0]`` is the header. Each row is a + list of ``(line_index, cell_text)`` pairs in column order, where + ``line_index`` is the 0-based index of the cell's line. + """ + + start_line: int + rows: list[list[tuple[int, str]]] + + +def iter_graph_tables(text: str) -> list[GraphTable]: + """Returns the graph tables (list-tables with a Download column) in text. + + Tables without a ``Download`` header cell are skipped, as are files' + non-table content. Only the flat one-cell-per-line layout used by the + docs graph tables is understood. + + Parameters + ---------- + text : str + The reStructuredText source of a docs page. + + Examples + -------- + >>> text = ( + ... ".. list-table::\n :header-rows: 1\n\n" + ... " * - Graph\n - Download\n" + ... " * - wc\n - `wc.tar.gz `_ 📥\n" + ... ) + >>> tables = iter_graph_tables(text) + >>> len(tables), [cell for _, cell in tables[0].rows[0]] + (1, ['Graph', 'Download']) + + Returns + ------- + tables : list[GraphTable] + The graph tables of the text, in order. + """ + lines = text.splitlines() + tables: list[GraphTable] = [] + i = 0 + while i < len(lines): + if lines[i].strip() != ".. list-table::": + i += 1 + continue + # The directive content runs until the next non-blank line at column 0. + j = i + 1 + while j < len(lines) and (not lines[j].strip() or lines[j][0] in " \t"): + j += 1 + table = _parse_table(lines, i, j) + if table is not None: + tables.append(table) + i = j + return tables + + +def _indent_of(lines: list[str], line_index: int) -> str: + """Returns the leading whitespace of a line.""" + line = lines[line_index] + return line[: len(line) - len(line.lstrip())] + + +def _parse_table(lines: list[str], start: int, end: int) -> Optional[GraphTable]: + """Parses the list-table at ``lines[start]`` or returns None.""" + rows: list[list[tuple[int, str]]] = [] + current: Optional[list[tuple[int, str]]] = None + for idx in range(start + 1, end): + row_match = _ROW_RE.match(lines[idx]) + if row_match is not None: + current = [(idx, row_match.group(2))] + rows.append(current) + continue + cell_match = _CELL_RE.match(lines[idx]) + if cell_match is not None and current is not None: + current.append((idx, cell_match.group(2))) + if not rows or DOWNLOAD_COLUMN not in [cell for _, cell in rows[0]]: + return None + return GraphTable(start_line=start, rows=rows) + + +def extract_url(cell: str) -> Optional[str]: + """Returns the URL of a download cell like `` `name.tar.gz `_ 📥 ``. + + Parameters + ---------- + cell : str + The text of a table cell. + + Examples + -------- + >>> extract_url("`wc.tar.gz `_ 📥") + 'https://example.com/wc.tar.gz' + >>> extract_url("no link here") is None + True + + Returns + ------- + url : str or None + The first http(s) URL in angle brackets, if any. + """ + match = _URL_RE.search(cell) + return match.group(1) if match is not None else None + + +def _head_size(url: str, timeout: float) -> int: + """Returns the Content-Length of a single HEAD request to url.""" + request = urllib.request.Request(url, method="HEAD") + with urllib.request.urlopen(request, timeout=timeout) as response: + length = response.headers.get("Content-Length") + if length is None: + raise RuntimeError(f"no Content-Length header in the HEAD response of {url}") + return int(length) + + +def _fetch_one(url: str, timeout: float) -> int: + """Fetches one size, retrying once.""" + last_error: Optional[Exception] = None + for _ in range(2): + try: + return _head_size(url, timeout) + except Exception as error: + last_error = error + raise RuntimeError(f"HEAD request to {url} failed: {last_error}") + + +def fetch_sizes( + urls: Iterable[str], *, timeout: float = 30.0, workers: int = 8 +) -> dict[str, int]: + """Returns the stored size in bytes of every URL (HEAD requests). + + Parameters + ---------- + urls : Iterable[str] + The archive URLs; duplicates are fetched once. + timeout : float, optional + Per-request timeout in seconds. Default: 30. + workers : int, optional + Number of concurrent HEAD requests. Default: 8. + + Examples + -------- + >>> fetch_sizes([]) + {} + + Returns + ------- + sizes : dict[str, int] + Mapping URL -> Content-Length in bytes. + + Raises + ------ + RuntimeError + If any URL cannot be fetched (after one retry); nothing is returned, + so callers can treat updates as all-or-nothing. + """ + unique = sorted(set(urls)) + sizes: dict[str, int] = {} + failures: list[str] = [] + with ThreadPoolExecutor(max_workers=workers) as pool: + futures = {pool.submit(_fetch_one, url, timeout): url for url in unique} + for future in as_completed(futures): + url = futures[future] + try: + sizes[url] = future.result() + except Exception as error: + failures.append(str(error)) + if failures: + raise RuntimeError( + "could not fetch the stored size of:\n " + "\n ".join(sorted(failures)) + ) + return sizes + + +def update_table(text: str, sizes: dict[str, int]) -> tuple[str, int]: + """Returns text with every graph table's Size (MB) column filled in. + + Where the column is missing it is inserted before the Download column + (header and all rows); where it exists, rows whose value disagrees with + ``sizes`` are fixed in place. Lines of tables that need no change keep + their exact text. + + Parameters + ---------- + text : str + The reStructuredText source of a docs page. + sizes : dict[str, int] + Mapping archive URL -> stored size in bytes (see :func:`fetch_sizes`). + + Examples + -------- + >>> text = ( + ... ".. list-table::\n :header-rows: 1\n\n" + ... " * - Graph\n - Download\n" + ... " * - wc\n - `wc.tar.gz `_ 📥\n" + ... ) + >>> updated, changed = update_table(text, {"https://example.com/wc.tar.gz": 2472}) + >>> changed + 1 + >>> "Size (MB)" in updated and "0.002" in updated + True + + Returns + ------- + updated : str + The new text. + changed : int + The number of data rows inserted or fixed. + """ + lines = text.splitlines() + insertions: list[tuple[int, str]] = [] + replacements: list[tuple[int, str]] = [] + changed = 0 + for table in iter_graph_tables(text): + header = table.rows[0] + download_index = next( + i for i, (_, cell) in enumerate(header) if cell == DOWNLOAD_COLUMN + ) + has_size = any(cell == SIZE_COLUMN for _, cell in header) + if not has_size: + line_index, _ = header[download_index] + indent = _indent_of(lines, line_index) + insertions.append((line_index, f"{indent}- {SIZE_COLUMN}")) + for row in table.rows[1:]: + if len(row) <= download_index: + continue + url = extract_url(row[download_index][1]) + if url is None or url not in sizes: + continue + value = format_size_mb(sizes[url]) + if has_size: + cell_index, current = row[download_index - 1] + if current != value: + indent = _indent_of(lines, cell_index) + replacements.append((cell_index, f"{indent}- {value}")) + changed += 1 + else: + line_index, _ = row[download_index] + indent = _indent_of(lines, line_index) + insertions.append((line_index, f"{indent}- {value}")) + changed += 1 + + for line_index, new_line in sorted(replacements, key=lambda p: p[0]): + lines[line_index] = new_line + for line_index, new_line in sorted(insertions, key=lambda p: p[0], reverse=True): + lines.insert(line_index, new_line) + + updated = "\n".join(lines) + if text.endswith("\n"): + updated += "\n" + return updated, changed + + +def _table_urls(text: str) -> list[str]: + """Returns the archive URLs referenced by the graph tables of text.""" + urls: list[str] = [] + for table in iter_graph_tables(text): + download_index = next( + i for i, (_, cell) in enumerate(table.rows[0]) if cell == DOWNLOAD_COLUMN + ) + for row in table.rows[1:]: + if len(row) <= download_index: + continue + url = extract_url(row[download_index][1]) + if url is not None: + urls.append(url) + return urls + + +def main(argv: Optional[Sequence[str]] = None) -> int: + """Command-line entry point. + + Check mode (default) exits with code 1 when any table row disagrees with + the stored object size; ``--update`` rewrites the tables instead. + + Returns + ------- + status : int + 0 when all graph tables are in sync (or were updated), 1 otherwise. + """ + parser = argparse.ArgumentParser( + description=( + "Check or update the Size (MB) column of the docs graph tables " + "against the stored archive sizes." + ) + ) + parser.add_argument( + "--update", + action="store_true", + help="rewrite the tables from the stored object sizes", + ) + args = parser.parse_args(argv) + + docs_dir = MAIN_FOLDER / "docs" + files = sorted( + path for pattern in GRAPH_TABLE_FILES for path in docs_dir.glob(pattern) + ) + texts = {path: path.read_text(encoding="utf-8") for path in files} + + urls = [url for text in texts.values() for url in _table_urls(text)] + if not urls: + print("No graph tables with download links found; nothing to do.") + return 1 + + try: + sizes = fetch_sizes(urls) + except RuntimeError as error: + print(f"error: {error}") + return 1 + + if args.update: + for path in files: + updated, changed = update_table(texts[path], sizes) + if changed: + path.write_text(updated, encoding="utf-8") + print(f"{path.relative_to(MAIN_FOLDER)}: updated {changed} row(s)") + print(f"Checked {len(urls)} archive(s); tables are in sync.") + return 0 + + problems: list[str] = [] + rows_checked = 0 + for path in files: + rel_path = path.relative_to(MAIN_FOLDER) + text = texts[path] + for table in iter_graph_tables(text): + header = [cell for _, cell in table.rows[0]] + download_index = header.index(DOWNLOAD_COLUMN) + has_size = SIZE_COLUMN in header + if not has_size: + problems.append( + f"{rel_path}:{table.start_line + 1}: no {SIZE_COLUMN} column" + ) + for row in table.rows[1:]: + rows_checked += 1 + name = row[0][1] + if len(row) <= download_index: + problems.append( + f"{rel_path}:{row[0][0] + 1}: {name}: no download link" + ) + continue + url = extract_url(row[download_index][1]) + if url is None or url not in sizes: + line_no = row[download_index][0] + 1 + problems.append( + f"{rel_path}:{line_no}: {name}: no fetchable download URL" + ) + continue + expected = format_size_mb(sizes[url]) + if has_size and row[download_index - 1][1] != expected: + size_cell = row[download_index - 1] + problems.append( + f"{rel_path}:{size_cell[0] + 1}: {name}: " + f"table says {size_cell[1]}, stored is {expected}" + ) + if problems: + print("\n".join(problems)) + print(f"FAILED: {len(problems)} problem(s) in {rows_checked} row(s).") + return 1 + print(f"OK: {rows_checked} row(s) in sync with the stored archive sizes.") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From 69586d957a9c81b9cd5b909e06c9266c6e0358ac Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 18:36:15 +0300 Subject: [PATCH 028/277] docs(40-S4): add the Size (MB) column to all nine graph tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Populated by running the new utils/archive_sizes.py in --update mode (dogfooding): one header cell and one size cell per row in the eight per-category tables (113 archives at the 5.0.0 prefix) and the old-graphs table (54 archives at the 4.0.0 prefix), 167 rows in total. MB is the single unit for all graphs because the archives span 0.002-112.65 MB — a range KB (up to ~110,000) and GB (all < 0.12) cannot scale to. Values were verified against live S3 Content-Length headers; check mode reports all 167 rows in sync and the no-warnings docs build passes. The Graphs page Contents section now documents the column. --- docs/graphs/biological_uniprot.rst | 11 +++++ docs/graphs/c_alias_analysis.rst | 21 ++++++++ docs/graphs/context_sensitive_data_flow.rst | 11 +++++ docs/graphs/data_provenance.rst | 19 +++++++ docs/graphs/field_sensitive_alias.rst | 11 +++++ docs/graphs/index.rst | 3 +- docs/graphs/java_points_to.rst | 22 +++++++++ docs/graphs/name_resolution.rst | 5 ++ docs/graphs/rdf.rst | 21 ++++++++ docs/old_graphs/index.rst | 55 +++++++++++++++++++++ 10 files changed, 178 insertions(+), 1 deletion(-) diff --git a/docs/graphs/biological_uniprot.rst b/docs/graphs/biological_uniprot.rst index 110de3ec..d8601e28 100644 --- a/docs/graphs/biological_uniprot.rst +++ b/docs/graphs/biological_uniprot.rst @@ -34,54 +34,65 @@ as in `"Subgraph queries by context-free grammars" `_ 📥 * - :ref:`unigraph_2` - 36467 - 168344 - 39888347 + - 0.581 - `unigraph_2.tar.gz `_ 📥 * - :ref:`unigraph_3` - 41332 - 193866 - 52471840 + - 0.667 - `unigraph_3.tar.gz `_ 📥 * - :ref:`unigraph_4` - 215480 - 1346130 - 808091802 + - 4.42 - `unigraph_4.tar.gz `_ 📥 * - :ref:`unigraph_5` - 243838 - 1818404 - 2303590109 + - 6.11 - `unigraph_5.tar.gz `_ 📥 * - :ref:`unigraph_6` - 286644 - 1708910 - 1722963921 + - 5.74 - `unigraph_6.tar.gz `_ 📥 * - :ref:`unigraph_7` - 285576 - 2073268 - 2320964134 + - 6.76 - `unigraph_7.tar.gz `_ 📥 * - :ref:`unigraph_8` - 449236 - 3385168 - not available + - 11.07 - `unigraph_8.tar.gz `_ 📥 * - :ref:`unigraph_9` - 475478 - 3579034 - not available + - 11.79 - `unigraph_9.tar.gz `_ 📥 * - :ref:`unigraph_10` - 2055881 - 17223588 - not available + - 56.24 - `unigraph_10.tar.gz `_ 📥 diff --git a/docs/graphs/c_alias_analysis.rst b/docs/graphs/c_alias_analysis.rst index 90fcd262..595e6419 100644 --- a/docs/graphs/c_alias_analysis.rst +++ b/docs/graphs/c_alias_analysis.rst @@ -44,104 +44,125 @@ discovered for each program. - Num Nodes - Num Edges - c_alias + - Size (MB) - Download * - :ref:`wc` - 332 - 269 - 156 + - 0.002 - `wc.tar.gz `_ 📥 * - :ref:`bzip` - 632 - 556 - 315 + - 0.004 - `bzip.tar.gz `_ 📥 * - :ref:`pr` - 815 - 692 - 385 + - 0.004 - `pr.tar.gz `_ 📥 * - :ref:`ls` - 1687 - 1453 - 854 + - 0.008 - `ls.tar.gz `_ 📥 * - :ref:`gzip` - 2687 - 2293 - 1458 + - 0.011 - `gzip.tar.gz `_ 📥 * - :ref:`apache` - 1721418 - 1510411 - 92806768 + - 9.05 - `apache.tar.gz `_ 📥 * - :ref:`init` - 2446224 - 2112809 - 3783769 + - 12.84 - `init.tar.gz `_ 📥 * - :ref:`mm` - 2538243 - 2191079 - 3990305 + - 13.33 - `mm.tar.gz `_ 📥 * - :ref:`ipc` - 3401022 - 2931498 - 5249389 + - 18.01 - `ipc.tar.gz `_ 📥 * - :ref:`lib` - 3401355 - 2931880 - 5276303 + - 18.01 - `lib.tar.gz `_ 📥 * - :ref:`block` - 3423234 - 2951393 - 5351409 + - 18.14 - `block.tar.gz `_ 📥 * - :ref:`arch` - 3448422 - 2970242 - 5339563 + - 18.25 - `arch.tar.gz `_ 📥 * - :ref:`crypto` - 3464970 - 2988387 - 5428237 + - 18.38 - `crypto.tar.gz `_ 📥 * - :ref:`security` - 3479982 - 3003326 - 5593387 + - 18.47 - `security.tar.gz `_ 📥 * - :ref:`sound` - 3528861 - 3049732 - 6085269 + - 18.77 - `sound.tar.gz `_ 📥 * - :ref:`net` - 4039470 - 3500141 - 8833403 + - 21.65 - `net.tar.gz `_ 📥 * - :ref:`fs` - 4177416 - 3609373 - 9646475 + - 22.34 - `fs.tar.gz `_ 📥 * - :ref:`drivers` - 4273803 - 3707769 - 18825025 + - 22.99 - `drivers.tar.gz `_ 📥 * - :ref:`postgre` - 5203419 - 4678543 - 90661446 + - 29.37 - `postgre.tar.gz `_ 📥 * - :ref:`kernel` - 11254434 - 9484213 - 16747731 + - 59.99 - `kernel.tar.gz `_ 📥 diff --git a/docs/graphs/context_sensitive_data_flow.rst b/docs/graphs/context_sensitive_data_flow.rst index 5e810a2b..0eee69a0 100644 --- a/docs/graphs/context_sensitive_data_flow.rst +++ b/docs/graphs/context_sensitive_data_flow.rst @@ -33,54 +33,65 @@ families), as in `"Taming Transitive Redundancy for Context-Free Language Reacha - Num Nodes - Num Edges - vf + - Size (MB) - Download * - :ref:`xz` - 30492 - 37173 - 358834 + - 0.144 - `xz.tar.gz `_ 📥 * - :ref:`nab` - 31215 - 37484 - 739646 + - 0.126 - `nab.tar.gz `_ 📥 * - :ref:`leela` - 47665 - 63996 - 662466 + - 0.242 - `leela.tar.gz `_ 📥 * - :ref:`x264` - 138702 - 201034 - 20259480 + - 0.714 - `x264.tar.gz `_ 📥 * - :ref:`parest` - 233900 - 307850 - 1342540 + - 1.17 - `parest.tar.gz `_ 📥 * - :ref:`imagick` - 331177 - 445544 - 12687034 + - 1.93 - `imagick.tar.gz `_ 📥 * - :ref:`povray` - 346034 - 581210 - 34599413 + - 2.34 - `povray.tar.gz `_ 📥 * - :ref:`cactus` - 359200 - 580297 - 47806209 + - 2.55 - `cactus.tar.gz `_ 📥 * - :ref:`omnetpp` - 463454 - 958487 - 8424500 + - 6.06 - `omnetpp.tar.gz `_ 📥 * - :ref:`perlbench` - 605864 - 1114892 - 297504186 + - 4.41 - `perlbench.tar.gz `_ 📥 diff --git a/docs/graphs/data_provenance.rst b/docs/graphs/data_provenance.rst index b95835db..9dfedcbd 100644 --- a/docs/graphs/data_provenance.rst +++ b/docs/graphs/data_provenance.rst @@ -41,94 +41,113 @@ Python projects, following the W3C PROV model (``Entity``, ``Activity``, - Num Nodes - Num Edges - prov_derivation + - Size (MB) - Download * - :ref:`provenance_sampleproject` - 148 - 763 - 342 + - 0.004 - `sampleproject.tar.gz `_ 📥 * - :ref:`provenance_wikipedia_provenance` - 316 - 1284 - 1732 + - 0.006 - `wikipedia-provenance.tar.gz `_ 📥 * - :ref:`provenance_pluggy` - 353 - 1818 - 880 + - 0.008 - `pluggy.tar.gz `_ 📥 * - :ref:`provenance_itsdangerous` - 425 - 2210 - 2912 + - 0.009 - `itsdangerous.tar.gz `_ 📥 * - :ref:`provenance_requests` - 682 - 3369 - 2524 + - 0.013 - `requests.tar.gz `_ 📥 * - :ref:`provenance_httpx` - 826 - 4247 - 4408 + - 0.016 - `httpx.tar.gz `_ 📥 * - :ref:`provenance_click` - 944 - 4654 - 2710 + - 0.017 - `click.tar.gz `_ 📥 * - :ref:`provenance_jinja` - 1202 - 6277 - 7436 + - 0.023 - `jinja.tar.gz `_ 📥 * - :ref:`provenance_flask` - 1517 - 7728 - 8062 + - 0.028 - `flask.tar.gz `_ 📥 * - :ref:`provenance_fastapi` - 6455 - 26528 - 8814 + - 0.090 - `fastapi.tar.gz `_ 📥 * - :ref:`provenance_celery` - 6880 - 35874 - 25306 + - 0.129 - `celery.tar.gz `_ 📥 * - :ref:`provenance_scikit_learn` - 11706 - 60181 - 217728 + - 0.210 - `scikit-learn.tar.gz `_ 📥 * - :ref:`provenance_sphinx` - 13431 - 72692 - 304084 + - 0.252 - `sphinx.tar.gz `_ 📥 * - :ref:`provenance_pandas` - 13696 - 70959 - 154646 + - 0.255 - `pandas.tar.gz `_ 📥 * - :ref:`provenance_django` - 23749 - 113137 - 615946 + - 0.415 - `django.tar.gz `_ 📥 * - :ref:`provenance_zulip` - 59854 - 310032 - 209908 + - 1.07 - `zulip.tar.gz `_ 📥 * - :ref:`provenance_superset` - 76348 - 394708 - 97460 + - 1.35 - `superset.tar.gz `_ 📥 * - :ref:`provenance_airflow` - 90673 - 454738 - 91350 + - 1.56 - `airflow.tar.gz `_ 📥 diff --git a/docs/graphs/field_sensitive_alias.rst b/docs/graphs/field_sensitive_alias.rst index 7b5dfa93..f10cbe2d 100644 --- a/docs/graphs/field_sensitive_alias.rst +++ b/docs/graphs/field_sensitive_alias.rst @@ -33,54 +33,65 @@ field (the ``f_i`` family), as in `"Taming Transitive Redundancy for Context-Fre - Num Nodes - Num Edges - aa + - Size (MB) - Download * - :ref:`xz_field_sensitive_alias` - 2808 - 6604 - 205164 + - 0.028 - `xz_field_sensitive_alias.tar.gz `_ 📥 * - :ref:`nab_field_sensitive_alias` - 3444 - 7982 - 262566 + - 0.035 - `nab_field_sensitive_alias.tar.gz `_ 📥 * - :ref:`leela_field_sensitive_alias` - 8090 - 19888 - 3968276 + - 0.086 - `leela_field_sensitive_alias.tar.gz `_ 📥 * - :ref:`povray_field_sensitive_alias` - 15137 - 38886 - 27219043 + - 0.161 - `povray_field_sensitive_alias.tar.gz `_ 📥 * - :ref:`x264_field_sensitive_alias` - 18051 - 44780 - 5246565 + - 0.201 - `x264_field_sensitive_alias.tar.gz `_ 📥 * - :ref:`cactus_field_sensitive_alias` - 22350 - 56636 - 37625324 + - 0.225 - `cactus_field_sensitive_alias.tar.gz `_ 📥 * - :ref:`parest_field_sensitive_alias` - 29788 - 64528 - 49415038 + - 0.290 - `parest_field_sensitive_alias.tar.gz `_ 📥 * - :ref:`perlbench_field_sensitive_alias` - 38091 - 110874 - 851737865 + - 0.447 - `perlbench_field_sensitive_alias.tar.gz `_ 📥 * - :ref:`imagick_field_sensitive_alias` - 41652 - 111550 - 369956094 + - 0.446 - `imagick_field_sensitive_alias.tar.gz `_ 📥 * - :ref:`omnetpp_field_sensitive_alias` - 49962 - 119064 - 158255766 + - 0.524 - `omnetpp_field_sensitive_alias.tar.gz `_ 📥 diff --git a/docs/graphs/index.rst b/docs/graphs/index.rst index d35f8ed8..07ee11f3 100644 --- a/docs/graphs/index.rst +++ b/docs/graphs/index.rst @@ -74,7 +74,8 @@ pairs ``(u, v)`` for which some string in the language labels a path from particular grammar: several grammars may generate the same language and yield the same count. A cell reading "not available" means the value has not been computed yet; an empty cell means the grammar does not apply to -that graph. +that graph. Each table also has a ``Size (MB)`` column: the download size +of the graph's archive, in megabytes. .. list-table:: :header-rows: 1 diff --git a/docs/graphs/java_points_to.rst b/docs/graphs/java_points_to.rst index 79578b63..6ca95c56 100644 --- a/docs/graphs/java_points_to.rst +++ b/docs/graphs/java_points_to.rst @@ -45,109 +45,131 @@ calls, returns) together with their reverses. - Num Nodes - Num Edges - java_points_to + - Size (MB) - Download * - :ref:`gson` - 14114 - 34934 - 56325 + - 0.189 - `gson.tar.gz `_ 📥 * - :ref:`sunflow` - 15464 - 15957 - 35209 + - 0.076 - `sunflow.tar.gz `_ 📥 * - :ref:`lusearch` - 15774 - 14994 - 43719 + - 0.079 - `lusearch.tar.gz `_ 📥 * - :ref:`luindex` - 18532 - 17375 - 176051 + - 0.095 - `luindex.tar.gz `_ 📥 * - :ref:`avrora` - 24690 - 25196 - 192790 + - 0.137 - `avrora.tar.gz `_ 📥 * - :ref:`mockito` - 25436 - 62388 - 16169 + - 0.349 - `mockito.tar.gz `_ 📥 * - :ref:`commons_io` - 26188 - 62428 - 24020 + - 0.342 - `commons_io.tar.gz `_ 📥 * - :ref:`commons_lang3` - 40970 - 96854 - 27553 + - 0.521 - `commons_lang3.tar.gz `_ 📥 * - :ref:`eclipse` - 41383 - 40200 - 378989 + - 0.201 - `eclipse.tar.gz `_ 📥 * - :ref:`h2` - 44717 - 56683 - 2611022 + - 0.256 - `h2.tar.gz `_ 📥 * - :ref:`pmd` - 54444 - 59329 - 137120 + - 0.280 - `pmd.tar.gz `_ 📥 * - :ref:`xalan` - 58476 - 62758 - 1138776 + - 0.309 - `xalan.tar.gz `_ 📥 * - :ref:`junit5` - 59818 - 149370 - 129598 + - 0.849 - `junit5.tar.gz `_ 📥 * - :ref:`batik` - 60175 - 63089 - 868368 + - 0.300 - `batik.tar.gz `_ 📥 * - :ref:`fop` - 86183 - 83016 - 1984072 + - 0.403 - `fop.tar.gz `_ 📥 * - :ref:`tomcat` - 111327 - 110884 - 3792543 + - 0.544 - `tomcat.tar.gz `_ 📥 * - :ref:`guava` - 129562 - 336232 - 26384496 + - 2.00 - `guava.tar.gz `_ 📥 * - :ref:`jackson` - 149404 - 395356 - 3108775 + - 2.33 - `jackson.tar.gz `_ 📥 * - :ref:`jython` - 191895 - 260034 - 561720 + - 1.04 - `jython.tar.gz `_ 📥 * - :ref:`tradebeans` - 439693 - 466969 - 34370090 + - 2.26 - `tradebeans.tar.gz `_ 📥 * - :ref:`tradesoap` - 440680 - 468263 - 34451130 + - 2.26 - `tradesoap.tar.gz `_ 📥 diff --git a/docs/graphs/name_resolution.rst b/docs/graphs/name_resolution.rst index d6664bfa..9bcd03e9 100644 --- a/docs/graphs/name_resolution.rst +++ b/docs/graphs/name_resolution.rst @@ -28,24 +28,29 @@ scopes. - Num Nodes - Num Edges - name_resolution + - Size (MB) - Download * - :ref:`name_resolution_jiaozi` - 54952 - 46322 - 14435 + - 0.240 - `jiaozi.tar.gz `_ 📥 * - :ref:`name_resolution_jsonpath` - 185421 - 161488 - 59764 + - 0.810 - `jsonpath.tar.gz `_ 📥 * - :ref:`name_resolution_shattered_pixel_dungeon` - 1179205 - 1017798 - 971998 + - 4.99 - `shattered_pixel_dungeon.tar.gz `_ 📥 * - :ref:`name_resolution_libgdx` - 2571363 - 2321366 - not available + - 11.27 - `libgdx.tar.gz `_ 📥 diff --git a/docs/graphs/rdf.rst b/docs/graphs/rdf.rst index d298d895..da93a376 100644 --- a/docs/graphs/rdf.rst +++ b/docs/graphs/rdf.rst @@ -46,6 +46,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`travel` - 131 @@ -62,6 +64,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`skos` - 144 @@ -70,6 +73,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`univ` - 179 @@ -78,6 +82,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`foaf` - 256 @@ -86,6 +91,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`atom` - 291 @@ -94,6 +100,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`people` - 337 @@ -102,6 +109,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`biomedical` - 341 @@ -110,6 +118,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`pizza` - 671 @@ -118,6 +127,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`wine` - 733 @@ -126,6 +136,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`funding` - 778 @@ -134,6 +145,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`core` - 1323 @@ -142,6 +154,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`pathways` - 6238 @@ -150,6 +163,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`go_hierarchy` - 45007 @@ -158,6 +172,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`enzyme` - 48815 @@ -166,6 +181,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`geospecies` - 450609 @@ -174,6 +190,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`go` - 582929 @@ -182,6 +199,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`eclass` - 239111 @@ -190,6 +208,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`taxonomy_hierarchy` - 2112625 @@ -198,6 +217,7 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 * - :ref:`taxonomy` - 5728398 @@ -206,4 +226,5 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 diff --git a/docs/old_graphs/index.rst b/docs/old_graphs/index.rst index e646b9b4..7c0758a1 100644 --- a/docs/old_graphs/index.rst +++ b/docs/old_graphs/index.rst @@ -26,220 +26,275 @@ Old graphs * - Graph - Num Nodes - Num Edges + - Size (MB) - Download * - :ref:`skos ` - 144 - 252 + - 0.002 - `skos.tar.gz `_ 📥 * - :ref:`wc ` - 332 - 269 + - 0.002 - `wc.tar.gz `_ 📥 * - :ref:`generations ` - 129 - 273 + - 0.002 - `generations.tar.gz `_ 📥 * - :ref:`travel ` - 131 - 277 + - 0.002 - `travel.tar.gz `_ 📥 * - :ref:`univ ` - 179 - 293 + - 0.002 - `univ.tar.gz `_ 📥 * - :ref:`atom ` - 291 - 425 + - 0.003 - `atom.tar.gz `_ 📥 * - :ref:`biomedical ` - 341 - 459 + - 0.003 - `biomedical.tar.gz `_ 📥 * - :ref:`bzip ` - 632 - 556 + - 0.004 - `bzip.tar.gz `_ 📥 * - :ref:`foaf ` - 256 - 631 + - 0.003 - `foaf.tar.gz `_ 📥 * - :ref:`people ` - 337 - 640 + - 0.004 - `people.tar.gz `_ 📥 * - :ref:`pr ` - 815 - 692 + - 0.004 - `pr.tar.gz `_ 📥 * - :ref:`funding ` - 778 - 1086 + - 0.006 - `funding.tar.gz `_ 📥 * - :ref:`ls ` - 1687 - 1453 + - 0.008 - `ls.tar.gz `_ 📥 * - :ref:`wine ` - 733 - 1839 + - 0.009 - `wine.tar.gz `_ 📥 * - :ref:`pizza ` - 671 - 1980 + - 0.009 - `pizza.tar.gz `_ 📥 * - :ref:`gzip ` - 2687 - 2293 + - 0.012 - `gzip.tar.gz `_ 📥 * - :ref:`core ` - 1323 - 2752 + - 0.013 - `core.tar.gz `_ 📥 * - :ref:`pathways ` - 6238 - 12363 + - 0.051 - `pathways.tar.gz `_ 📥 * - :ref:`lusearch ` - 15774 - 14994 + - 0.072 - `lusearch.tar.gz `_ 📥 * - :ref:`sunflow ` - 15464 - 15957 + - 0.073 - `sunflow.tar.gz `_ 📥 * - :ref:`luindex ` - 18532 - 17375 + - 0.084 - `luindex.tar.gz `_ 📥 * - :ref:`avrora ` - 24690 - 25196 + - 0.118 - `avrora.tar.gz `_ 📥 * - :ref:`eclipse ` - 41383 - 40200 + - 0.188 - `eclipse.tar.gz `_ 📥 * - :ref:`h2 ` - 44717 - 56683 + - 0.244 - `h2.tar.gz `_ 📥 * - :ref:`pmd ` - 54444 - 59329 + - 0.262 - `pmd.tar.gz `_ 📥 * - :ref:`xalan ` - 58476 - 62758 + - 0.285 - `xalan.tar.gz `_ 📥 * - :ref:`batik ` - 60175 - 63089 + - 0.285 - `batik.tar.gz `_ 📥 * - :ref:`fop ` - 86183 - 83016 + - 0.383 - `fop.tar.gz `_ 📥 * - :ref:`enzyme ` - 48815 - 86543 + - 0.398 - `enzyme.tar.gz `_ 📥 * - :ref:`tomcat ` - 111327 - 110884 + - 0.506 - `tomcat.tar.gz `_ 📥 * - :ref:`jython ` - 191895 - 260034 + - 1.08 - `jython.tar.gz `_ 📥 * - :ref:`eclass ` - 239111 - 360248 + - 1.74 - `eclass.tar.gz `_ 📥 * - :ref:`tradebeans ` - 439693 - 466969 + - 2.15 - `tradebeans.tar.gz `_ 📥 * - :ref:`tradesoap ` - 440680 - 468263 + - 2.16 - `tradesoap.tar.gz `_ 📥 * - :ref:`go_hierarchy ` - 45007 - 490109 + - 1.72 - `go_hierarchy.tar.gz `_ 📥 * - :ref:`go ` - 582929 - 1437437 + - 7.47 - `go.tar.gz `_ 📥 * - :ref:`apache ` - 1721418 - 1510411 + - 9.58 - `apache.tar.gz `_ 📥 * - :ref:`init ` - 2446224 - 2112809 + - 13.56 - `init.tar.gz `_ 📥 * - :ref:`mm ` - 2538243 - 2191079 + - 14.08 - `mm.tar.gz `_ 📥 * - :ref:`geospecies ` - 450609 - 2201532 + - 9.44 - `geospecies.tar.gz `_ 📥 * - :ref:`ipc ` - 3401022 - 2931498 + - 19.03 - `ipc.tar.gz `_ 📥 * - :ref:`lib ` - 3401355 - 2931880 + - 19.03 - `lib.tar.gz `_ 📥 * - :ref:`block ` - 3423234 - 2951393 + - 19.16 - `block.tar.gz `_ 📥 * - :ref:`arch ` - 3448422 - 2970242 + - 19.28 - `arch.tar.gz `_ 📥 * - :ref:`crypto ` - 3464970 - 2988387 + - 19.41 - `crypto.tar.gz `_ 📥 * - :ref:`security ` - 3479982 - 3003326 + - 19.51 - `security.tar.gz `_ 📥 * - :ref:`sound ` - 3528861 - 3049732 + - 19.83 - `sound.tar.gz `_ 📥 * - :ref:`net ` - 4039470 - 3500141 + - 22.88 - `net.tar.gz `_ 📥 * - :ref:`fs ` - 4177416 - 3609373 + - 23.60 - `fs.tar.gz `_ 📥 * - :ref:`drivers ` - 4273803 - 3707769 + - 24.29 - `drivers.tar.gz `_ 📥 * - :ref:`postgre ` - 5203419 - 4678543 + - 31.09 - `postgre.tar.gz `_ 📥 * - :ref:`kernel ` - 11254434 - 9484213 + - 63.62 - `kernel.tar.gz `_ 📥 * - :ref:`taxonomy ` - 5728398 - 14922125 + - 69.63 - `taxonomy.tar.gz `_ 📥 * - :ref:`taxonomy_hierarchy ` - 2112625 - 32876289 + - 112.65 - `taxonomy_hierarchy.tar.gz `_ 📥 From 5edfd63191d14355d8dcd24ffe3559b866b98a46 Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 18:41:45 +0300 Subject: [PATCH 029/277] feat(40-S5): report the verified archive size from the upload tool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a new graph is added its table row must carry the Size (MB) value, so the upload tool now surfaces the size it already computes and verifies: upload_file() returns (key, stored_size) — the head_object ContentLength that must equal the local file size — and the CLI prints it in bytes and megabytes using sizes.format_size_mb, the same formatting as the docs tables. The reported number is therefore exactly what utils/archive_sizes.py reads back from S3, so a row filled from the upload output always passes check mode. The only other callers (migrate_gdrive_to_s3, convert_old_to_new) use the return value as a statement and are unaffected. The Upload section of docs/utils.rst documents the new output. --- docs/utils.rst | 5 ++++- tests/utils/test_upload_to_s3.py | 36 +++++++++++++++++++++++++++----- utils/upload_to_s3.py | 19 ++++++++++++----- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/docs/utils.rst b/docs/utils.rst index 056581a8..d144b02b 100644 --- a/docs/utils.rst +++ b/docs/utils.rst @@ -35,7 +35,10 @@ Upload to Yandex S3 ``5.0.0/graph/NAME.tar.gz`` to follow the dataset layout). After the upload the tool verifies that the stored object size equals the -local file size and reports an error otherwise. +local file size and reports an error otherwise. The verified size is then +reported in bytes and megabytes, with the same MB formatting as the +``Size (MB)`` column of the graph tables, so a new graph's table row can be +filled directly from the upload output. .. _migrate_gdrive_to_s3: diff --git a/tests/utils/test_upload_to_s3.py b/tests/utils/test_upload_to_s3.py index f308010e..7ad684b2 100644 --- a/tests/utils/test_upload_to_s3.py +++ b/tests/utils/test_upload_to_s3.py @@ -47,15 +47,16 @@ def fake_client(service, **kwargs): assert calls["endpoint_url"] == DEFAULT_ENDPOINT_URL == "https://s3.yandexcloud.net" -def test_upload_file_uploads_and_returns_key(tmp_path): +def test_upload_file_uploads_and_returns_key_and_size(tmp_path): file = tmp_path / "graph.tar.gz" file.write_bytes(b"payload") client = mock.Mock() client.head_object.return_value = {"ContentLength": 7} - key = upload_file(client, file, "cfpq-data", key="4.0.0/graph/graph.tar.gz") + key, size = upload_file(client, file, "cfpq-data", key="4.0.0/graph/graph.tar.gz") assert key == "4.0.0/graph/graph.tar.gz" + assert size == 7 client.upload_file.assert_called_once_with( str(file), "cfpq-data", "4.0.0/graph/graph.tar.gz" ) @@ -70,9 +71,10 @@ def test_upload_file_default_key_is_file_name(tmp_path): client = mock.Mock() client.head_object.return_value = {"ContentLength": 7} - key = upload_file(client, file, "cfpq-data") + key, size = upload_file(client, file, "cfpq-data") assert key == "graph.tar.gz" + assert size == 7 def test_upload_file_missing_local_file(tmp_path): @@ -127,7 +129,7 @@ def test_copy_object_size_mismatch_raises(): copy_object(client, "cfpq-data", "a.tar.gz", "b.tar.gz") -def test_main_uploads_file(tmp_path, monkeypatch, capsys): +def test_main_uploads_file_and_reports_size(tmp_path, monkeypatch, capsys): file = tmp_path / "graph.tar.gz" file.write_bytes(b"payload") client = mock.Mock() @@ -145,10 +147,34 @@ def test_main_uploads_file(tmp_path, monkeypatch, capsys): ) out = capsys.readouterr().out - assert f"Uploaded {file} to s3://{DEFAULT_BUCKET}/graph.tar.gz" in out + assert ( + f"Uploaded {file} to s3://{DEFAULT_BUCKET}/graph.tar.gz " + "(7 bytes, 0.000 MB)" in out + ) client.upload_file.assert_called_once() +def test_main_reports_size_above_one_megabyte(tmp_path, monkeypatch, capsys): + file = tmp_path / "graph.tar.gz" + file.write_bytes(b"x" * 2_500_000) + client = mock.Mock() + client.head_object.return_value = {"ContentLength": 2_500_000} + monkeypatch.setattr("upload_to_s3.boto3.client", lambda *args, **kwargs: client) + + main( + [ + str(file), + "--access-key-id", + "key-id", + "--secret-access-key", + "secret", + ] + ) + + out = capsys.readouterr().out + assert "(2500000 bytes, 2.50 MB)" in out + + def test_main_requires_credentials(tmp_path): file = tmp_path / "graph.tar.gz" file.write_bytes(b"payload") diff --git a/utils/upload_to_s3.py b/utils/upload_to_s3.py index 3be79500..16942d1e 100644 --- a/utils/upload_to_s3.py +++ b/utils/upload_to_s3.py @@ -7,6 +7,7 @@ import boto3 from botocore.client import BaseClient +from sizes import format_size_mb __all__ = [ "DEFAULT_ENDPOINT_URL", @@ -56,7 +57,7 @@ def upload_file( local_path: Union[str, pathlib.Path], bucket: str, key: Optional[str] = None, -) -> str: +) -> tuple[str, int]: """Upload a local file to an S3 bucket and verify the stored size. Parameters @@ -74,6 +75,11 @@ def upload_file( ------- key : str The object key the file was stored under. + size : int + The verified size of the stored object in bytes (equal to the local + file size; the upload is aborted otherwise). The CLI reports it in + MB with the same formatting as the ``Size (MB)`` column of the docs + graph tables. Raises ------ @@ -98,8 +104,8 @@ def upload_file( f"stored size {stored_size} != local size {local_size}" ) - logging.info(f"Uploaded {local_path} to s3://{bucket}/{key}") - return key + logging.info(f"Uploaded {local_path} to s3://{bucket}/{key} ({stored_size} bytes)") + return key, stored_size def copy_object( @@ -191,8 +197,11 @@ def main(argv: Optional[Sequence[str]] = None) -> None: client = create_s3_client( args.access_key_id, args.secret_access_key, args.endpoint_url ) - key = upload_file(client, args.file, args.bucket, args.key) - print(f"Uploaded {args.file} to s3://{args.bucket}/{key}") + key, size = upload_file(client, args.file, args.bucket, args.key) + print( + f"Uploaded {args.file} to s3://{args.bucket}/{key} " + f"({size} bytes, {format_size_mb(size)} MB)" + ) if __name__ == "__main__": From 2a7169068f94a7f41028b1823d08f8c2fbe6d242 Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 18:46:26 +0300 Subject: [PATCH 030/277] docs(40-S6): document the archive size tooling and the new-graph flow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'Archive sizes' section of docs/utils.rst documents utils/archive_sizes.py (coverage, check vs --update, all-or-nothing writes, URL keying) next to the upload section it complements. The add-graph skill gains the size step — fill the new row's Size (MB) cell from the upload output and run archive_sizes.py --update before committing — and its registration step now points at the per-category table where graph rows actually live (plus the category count in the Contents table). The changelog records both user-visible additions. --- .opencode/skills/add-graph/SKILL.md | 13 +++++++---- CHANGELOG.md | 7 ++++++ docs/utils.rst | 36 +++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/.opencode/skills/add-graph/SKILL.md b/.opencode/skills/add-graph/SKILL.md index 15a8b245..a8782037 100644 --- a/.opencode/skills/add-graph/SKILL.md +++ b/.opencode/skills/add-graph/SKILL.md @@ -36,10 +36,15 @@ The archive layout and the label conventions are documented once in the 1. Create the per-graph page `docs/graphs/data/.rst`, following the structure of an existing page (description, statistics tables, canonical grammars). Statistics conventions: the PR template is the source of truth. -2. Register it in `docs/graphs/index.rst` **twice**: a row in the section - table of its source area, and an entry in the matching captioned toctree - (the left navigation bar is generated from those toctrees). Keep both in - the same order as the table. +2. Register it **twice**: a row in the per-category table of its source area + (`docs/graphs/.rst`) and an entry in the matching captioned + toctree of `docs/graphs/index.rst` (the left navigation bar is generated + from those toctrees). Keep both in the same order, and bump the category's + graph count in the Contents table of `docs/graphs/index.rst`. +3. Fill the new row's `Size (MB)` cell with the size the upload tool + reported, then run `python utils/archive_sizes.py --update` before + committing so every table row — including the new one — matches S3 (see + the "Archive sizes" section of `docs/utils.rst`). Note: a `data/*.rst` page missing from all toctrees produces only a Sphinx *warning*, not an error, so the docs quality gate will not catch it — check diff --git a/CHANGELOG.md b/CHANGELOG.md index 1234a442..c33a4ddd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- The graph tables on the website now list the download size of every + archive in a `Size (MB)` column — one unit (MB) for all graphs, from the + smallest (0.002 MB) to the largest (112.65 MB) archive. +- `utils/upload_to_s3.py` reports the verified archive size (bytes and MB) + after each upload, and the new `utils/archive_sizes.py` checks or updates + the `Size (MB)` column of the docs graph tables against the stored + archives on Yandex S3. - The publish workflow now runs on every pull request targeting `master`: it builds the sdist and wheel and publishes them to TestPyPI (`skip-existing`), validating packaging before a release tag is cut. diff --git a/docs/utils.rst b/docs/utils.rst index d144b02b..f909aa2b 100644 --- a/docs/utils.rst +++ b/docs/utils.rst @@ -40,6 +40,42 @@ reported in bytes and megabytes, with the same MB formatting as the ``Size (MB)`` column of the graph tables, so a new graph's table row can be filled directly from the upload output. +.. _archive_sizes: + +Archive sizes +------------- + +``utils/archive_sizes.py`` keeps the ``Size (MB)`` column of the graph tables +in sync with the stored archives:: + + python utils/archive_sizes.py [--update] + +The tool covers every list-table with a ``Download`` column in +``docs/graphs/*.rst`` and ``docs/old_graphs/index.rst`` — currently the eight +per-category tables (113 archives at the ``5.0.0/graph/`` prefix) and the +old-graphs table (54 archives at the ``4.0.0/graph/`` prefix). For every +referenced archive it issues an S3 ``HEAD`` request and compares the +``Content-Length`` with the table cell, formatted in MB (three decimals below +one megabyte, two from one up — the rule lives in ``utils/sizes.py`` and is +shared with :ref:`upload_to_s3`). + +Behavior: + +- **Check mode (default).** Reports every row whose size cell disagrees with + the stored object (or a missing column or link) and exits non-zero, so it + can gate a commit. +- **``--update``.** Fetches all sizes first, then rewrites the tables — + inserting the ``Size (MB)`` column before ``Download`` where it is missing + and fixing drifted cells. All-or-nothing: if any archive cannot be fetched, + nothing is written. +- **URL keying.** Sizes are keyed by full URL, not archive name: the + ``4.0.0`` and ``5.0.0`` prefixes hold same-named archives with different + content. + +When adding a new graph, upload it first (:ref:`upload_to_s3` prints the +verified size), add the table row with that value, and run this tool before +committing so every row — including the new one — matches S3. + .. _migrate_gdrive_to_s3: Migrate from Google Drive From afdccf3c90949639e7fcc010b01b2ace0bcfbf9c Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 19:11:52 +0300 Subject: [PATCH 031/277] fix(40-S3): keep rows without a fetchable URL aligned in update mode Code review found that when the Size (MB) column was missing, a row whose download cell held no URL got no size cell at all, producing a table with ragged rows. Such rows now get a bare '-' cell (the same empty-cell style rdf.rst uses for non-applicable grammars), keeping every row aligned; check mode still flags the missing link. Also fixed the GRAPH_TABLE_FILES comment: the patterns are relative to docs/, not the repository root. --- tests/utils/test_archive_sizes.py | 26 ++++++++++++++++++++++++++ utils/archive_sizes.py | 13 ++++++++----- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/tests/utils/test_archive_sizes.py b/tests/utils/test_archive_sizes.py index 7cc5abbd..a61219a3 100644 --- a/tests/utils/test_archive_sizes.py +++ b/tests/utils/test_archive_sizes.py @@ -237,6 +237,32 @@ def test_update_table_with_empty_cells(): ] +def test_update_table_keeps_rows_without_url_aligned(): + text = ( + ".. list-table::\n" + " :header-rows: 1\n" + "\n" + " * - Graph\n" + " - Download\n" + " * - :ref:`wc`\n" + f" - `wc.tar.gz <{WC_URL}>`_ 📥\n" + " * - :ref:`broken`\n" + " - no link here\n" + ) + + updated, changed = update_table(text, SIZES) + + assert changed == 2 + table = iter_graph_tables(updated)[0] + # The broken row gets a bare '-' cell so the columns stay aligned. + assert [cell for _, cell in table.rows[1]] == [ + ":ref:`wc`", + "0.002", + f"`wc.tar.gz <{WC_URL}>`_ 📥", + ] + assert [cell for _, cell in table.rows[2]] == [":ref:`broken`", "", "no link here"] + + def test_update_table_leaves_non_graph_tables_untouched(): text = ( ".. list-table::\n" diff --git a/utils/archive_sizes.py b/utils/archive_sizes.py index 293a3fbf..00bf7424 100644 --- a/utils/archive_sizes.py +++ b/utils/archive_sizes.py @@ -44,7 +44,7 @@ #: The download-column header every graph table must have to be processed. DOWNLOAD_COLUMN = "Download" -#: The docs files holding graph tables, relative to the repository root. +#: The docs files holding graph tables, as glob patterns relative to docs/. GRAPH_TABLE_FILES: tuple[str, ...] = ( "graphs/*.rst", "old_graphs/index.rst", @@ -291,18 +291,21 @@ def update_table(text: str, sizes: dict[str, int]) -> tuple[str, int]: continue url = extract_url(row[download_index][1]) if url is None or url not in sizes: - continue - value = format_size_mb(sizes[url]) + value = "" + else: + value = format_size_mb(sizes[url]) if has_size: cell_index, current = row[download_index - 1] - if current != value: + if value and current != value: indent = _indent_of(lines, cell_index) replacements.append((cell_index, f"{indent}- {value}")) changed += 1 else: + # A bare '-' line keeps the row aligned when no value is known. line_index, _ = row[download_index] indent = _indent_of(lines, line_index) - insertions.append((line_index, f"{indent}- {value}")) + cell = f"{indent}- {value}" if value else f"{indent}-" + insertions.append((line_index, cell)) changed += 1 for line_index, new_line in sorted(replacements, key=lambda p: p[0]): From f8a27c5b0926d99e88d990936383300528fadf0c Mon Sep 17 00:00:00 2001 From: gsv Date: Thu, 17 Sep 2026 19:33:57 +0300 Subject: [PATCH 032/277] docs(40-S7): mark task 40 done in the task log All subtasks are committed and verified: the nine graph tables carry the Size (MB) column (167 rows, MB as the single unit), the upload tool reports the verified archive size, and utils/archive_sizes.py keeps the column in sync with S3 for future additions. The quality gate passed in full: 363 tests, ruff check and format, ty, the no-warnings docs build, and the link check (a first linkcheck run hit Wikipedia rate limiting on two pre-existing URLs; both verified 200 directly and the re-run was clean). --- tasks/tasks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/tasks.md b/tasks/tasks.md index 80f35e28..b0bcc259 100644 --- a/tasks/tasks.md +++ b/tasks/tasks.md @@ -39,4 +39,4 @@ - [done] Task 37: Migrate project to UV manager (https://github.com/astral-sh/uv) WE need full migration: no requirements.txt, no other legacy sfuff. Configure project to use UV-provided tools for quality checking: linter, type checker, etc. Do not forget to update documentation. **[USER GUIDANCE]**: "Read https://docs.astral.sh/uv/guides/integration/pre-commit/ can we use official UV pre-commit hooks?" / "Note on ty typechecker. Let use ty for fast check but in CI use both ty and pyright." / "Delete both (Recommended)" (broken legacy scripts utils/fetch_dataset.py and utils/update_dataset_tables.py) - [done] Task 38: We use mechanism to close issues automatically described here: https://github.blog/news-insights/product-news/closing-issues-via-commit-messages/ Improve imstructions to write respective commut message when task is link to issue. - [done] Task 39: Fix https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/94 -- [ ] Task 40: For the site, add archive sizes (size to download) to tables with graphs. Add one new column to each table (for each category). Choose one unit of neasure for all graphs (Kb, Mb or Gb). Moreover, improve tool that uploads new graph. It should compute archive size. When new raph added, table must be updated. So computed size used for it. **[USER GUIDANCE]**: "Include old graphs (Recommended)" / "Add a reusable utils script" +- [done] Task 40: For the site, add archive sizes (size to download) to tables with graphs. Add one new column to each table (for each category). Choose one unit of neasure for all graphs (Kb, Mb or Gb). Moreover, improve tool that uploads new graph. It should compute archive size. When new raph added, table must be updated. So computed size used for it. **[USER GUIDANCE]**: "Include old graphs (Recommended)" / "Add a reusable utils script" From c72517823fc642957390775575c6bdfc42d14389 Mon Sep 17 00:00:00 2001 From: gsv Date: Fri, 18 Sep 2026 09:31:18 +0300 Subject: [PATCH 033/277] docs(41-S1): record task 41 in the task log and write the detailed plan Canonical grammars are a property of a graph category, not of an individual graph: the same text is currently repeated on every graph page of a category (up to 21 times), via copy-pasted inline sections and five .inc includes. The category pages already carry one table column per grammar language, so they are the single home for the canonical grammar description. Graph pages lose the section entirely; docs/old_graphs (legacy, no category structure) stays untouched; the rdf category page gets the union of all four grammars. The graph PR/issue templates gain a Category field and cover three contribution cases: existing category, new grammar for an existing category, new category. --- tasks/detailed_plan.md | 336 +++++++++++++++++++---------------------- tasks/tasks.md | 1 + 2 files changed, 158 insertions(+), 179 deletions(-) diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index 008ae248..25e32833 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -1,199 +1,177 @@ -# Detailed Plan: Task 40 — Archive sizes on the site + upload tool size computation +# Detailed Plan: Task 41 — Move canonical grammar descriptions from graph pages to category pages ## Task -For the site, add archive sizes (size to download) to tables with graphs. Add -one new column to each table (for each category). Choose one unit of measure -for all graphs (Kb, Mb or Gb). Moreover, improve the tool that uploads a new -graph — it should compute the archive size. When a new graph is added, the -table must be updated; the computed size is used for it. - -**[USER GUIDANCE]**: "Include old graphs (Recommended)" / "Add a reusable -utils script" - -## Decisions (verified against live data, 2026-09-17) - -- **Unit: MB** (decimal, 10^6 bytes), one unit for all graphs. All 167 - archives measured via S3 HEAD (`Content-Length`): - - `5.0.0/graph/` (113 graphs): 2,472 B – 99,645,647 B → 0.002 – 99.65 MB; - - `4.0.0/graph/` (54 old graphs): 2,078 B – 112,652,191 B → 0.002 – 112.65 MB. - KB would reach ~110,000; GB would make every value < 0.12. -- **Formatting rule** (single shared function): `< 1` MB → 3 decimals - (`0.002`, `0.988`); `>= 1` MB → 2 decimals (`1.02`, `57.21`, `99.65`). -- **Column**: header `Size (MB)`, inserted immediately before the existing - `Download` column in every table. -- **Scope**: all 9 graph tables — the 8 per-category pages - (`docs/graphs/{c_alias_analysis,rdf,java_points_to,field_sensitive_alias, - context_sensitive_data_flow,data_provenance,name_resolution, - biological_uniprot}.rst`) and `docs/old_graphs/index.rst`. The benchmarks - table is excluded (it lists benchmark archives, not graphs). Per-graph Info - pages are unchanged. -- **No new state file**: the S3 bucket is the source of truth for archive - sizes. The upload tool reports the size it verifies at upload time; the - table tool fetches the same values from S3. Nothing to keep in sync in the - repo besides the tables themselves. -- **URL keying**: sizes are keyed by full URL, not archive name — the 4.0.0 - and 5.0.0 prefixes contain same-named archives with different content - (old CSV format vs new mtx-per-label format). - -## Reuse analysis (reusing skill) - -- `utils/config.py:MAIN_FOLDER` — reused to anchor the docs paths so the tool - runs from any CWD. -- `utils/audit_info_tables.py` — line-based RST list-table parsing style and - module layout (docstring + usage, `__all__`, pure functions with numpydoc - docstrings, `main(argv)` with argparse) reused as the template for - `archive_sizes.py`. -- `tests/utils/conftest.py` already puts `utils/` on `sys.path`; new tests - follow `tests/utils/test_upload_to_s3.py` conventions (mocked clients, no - network in the test suite). -- `upload_file()` in `utils/upload_to_s3.py` already computes and verifies - the stored size (`head_object` vs local stat) — S5 only surfaces it. -- No existing size-formatting code anywhere (searched `cfpq_data/`, - `utils/`, `docs/`) — `utils/sizes.py` is genuinely new. +Analyze structure of the site. Looks like better place for canonical grammars +description is category page, not graph. Because grammar canonical for category. + +**[USER GUIDANCE]**: "On issue and request teplamtes. If graph for existing +category, then ok. But we can have at least two more options. Graph for new +category. Then grammars should be provided. New grammar for existing category." +/ "Nothing (Recommended)" (graph pages keep no grammar section or pointer) / +"Leave as-is (Recommended)" (docs/old_graphs legacy pages untouched) / +"All 4 grammars (Recommended)" (rdf category page lists the union incl. +broaderTransitive) / "Yes, add it (Recommended)" (Category row in both graph +templates) + +## Analysis (verified against the tree, 2026-09-18) + +Site layout: `docs/dataset.rst` toctree → `graphs/index` → 8 category pages +(`docs/graphs/.rst`) → 113 graph pages (`docs/graphs/data/*.rst`). +Separately, `docs/grammars/` holds 4 parameterized *template* pages +(nested_parentheses, dyck, c_alias, java_points_to) — different purpose, kept. + +7 distinct canonical grammar texts are each repeated on every graph page of +its category: + +| Category | Pages | Current duplication | +|---|---|---| +| c_alias_analysis | 20 | identical inline section (incl. `change_edges` note, 2 variants) | +| rdf | 20 | inline; 19 identical + geospecies has a 4th grammar (broaderTransitive) | +| biological_uniprot | 10 | identical inline section | +| java_points_to | 21 | inconsistent: 14 pages inline + 7 via `.. include::` | +| field_sensitive_alias | 10 | `.. include:: grammar_cpu17_field_sensitive_alias.inc` | +| context_sensitive_data_flow | 10 | `.. include:: grammar_cpu17_context_sensitive_data_flow.inc` | +| data_provenance | 18 | `.. include:: grammar_data_provenance.inc` | +| name_resolution | 4 | `.. include:: grammar_name_resolution.inc` | + +5 `.inc` files live in `docs/graphs/data/`. No tooling (utils/, tests/, +cfpq_data/) references them. Docs build is nitpicky with a no-warnings policy, +so it catches dangling refs. + +## Decisions + +- Grammar text moves **verbatim** to the category page, appended after the + per-category graph table (the table already has one column per grammar + language — the description belongs with it). +- Section heading normalized to `Canonical grammars` on all 8 category pages + (sources use "Canonical grammars" / "Canonical Grammar" / "Grammar"). +- Graph pages: section removed entirely, nothing left in its place (user + decision). The category page is the parent in the toctree/nav. +- `docs/old_graphs/` (54 legacy pages, orphan page, no category structure): + untouched (user decision). +- rdf category page: union of all 4 grammars (3 shared + broaderTransitive), + keeping the `----` separators (user decision). +- Cross-reference lines to `docs/grammars/` template pages + (`:ref:`java_points-to``, `:ref:`c_alias``, `:ref:`nested_parentheses``) + are kept — they tie the concrete canonical grammar to its parameterized + template. +- Docs-only task: no `.py` changes; code gates (tests/lint/format) skipped, + docs build gate applies. ## Subtasks -### S1: Record task, create branch, write this plan +### S1: Record task 41 in the task log and write the detailed plan -**Code:** none. -**Tests:** none. -**Docs:** `tasks/tasks.md` (task line), `tasks/detailed_plan.md` (this file). +**Code:** n/a. Modify `tasks/tasks.md`, `tasks/detailed_plan.md`. +**Tests:** n/a. +**Docs:** n/a (task tracking files). **Spec:** -- Task 40 logged in `tasks/tasks.md` with the user's description verbatim and - the two Q&A decisions as **[USER GUIDANCE]**. -- Feature branch `feature/40-archive-sizes` created from `dev`. - -### S2: Shared size formatting — `utils/sizes.py` - -**Code:** New `utils/sizes.py` with `format_size_mb(size_bytes: int) -> str` -implementing the formatting rule above (decimal MB; 3 decimals below 1, 2 -decimals from 1 up). numpydoc docstring with doctest-stable `Examples`. -**Tests:** New `tests/utils/test_sizes.py`: boundary values (0 B, 999,999 B → -`0.999`, 1,000,000 B → `1.00`, 1,021,000 B → `1.02`), real archive sizes -(wc 2,472 B → `0.002`; taxonomy_hierarchy 112,652,191 B → `112.65`), and the -doctest examples. -**Docs:** none (maintainer-internal module; documented where used in S3/S5). +- Append Task 41 to `tasks/tasks.md` with the user's description verbatim and + the `[USER GUIDANCE]` annotations. +- Write this detailed plan. + +### S2: Add "Canonical grammars" section to the 5 .inc-based category pages + +**Code:** n/a (docs-only). Modify `docs/graphs/java_points_to.rst`, +`docs/graphs/field_sensitive_alias.rst`, +`docs/graphs/context_sensitive_data_flow.rst`, +`docs/graphs/data_provenance.rst`, `docs/graphs/name_resolution.rst`. +**Tests:** n/a — verified by the docs build (S6). +**Docs:** the 5 category pages gain a `Canonical grammars` section after the +graph table, content moved verbatim from `grammar_java_points_to.inc`, +`grammar_cpu17_field_sensitive_alias.inc`, +`grammar_cpu17_context_sensitive_data_flow.inc`, +`grammar_data_provenance.inc`, `grammar_name_resolution.inc` respectively; +headings normalized to `Canonical grammars`; template-page cross-references +kept. **Spec:** -- Pure function, no I/O, no dependencies; importable as top-level `sizes` - (conftest puts `utils/` on `sys.path`). -- The formatting rule lives here and ONLY here — both `archive_sizes.py` and - `upload_to_s3.py` import it (single source of truth). - -### S3: Table tool — `utils/archive_sizes.py` - -**Code:** New `utils/archive_sizes.py`: -- `iter_graph_tables(text: str) -> list[GraphTable]` — line-based parser for - RST `list-table`s whose header row contains a `Download` cell; returns the - table's rows (each row = list of `(line_index, cell_text)` pairs) so both - check and update can operate on it. Tables without a `Download` header are - skipped (e.g. the Contents table in `docs/graphs/index.rst`). -- `extract_url(cell: str) -> str | None` — pulls the `https://…` target out of - a `` `name.tar.gz `_ 📥 `` cell. -- `fetch_sizes(urls: Iterable[str], timeout: float = 30.0, workers: int = 8) - -> dict[str, int]` — HEAD each unique URL (stdlib `urllib.request`, - `ThreadPoolExecutor`), one retry per URL, returns `{url: content_length}`; - raises `RuntimeError` listing the failed URLs so updates are all-or-nothing. -- `update_table(text: str, sizes: dict[str, int]) -> tuple[str, int]` — - rewrites every graph table in the text: inserts a `Size (MB)` header cell - before `Download` where missing and fills/fixes each row's size cell with - `format_size_mb`; returns the new text and the number of changed rows. -- `main(argv) -> int` — default **check mode**: parse - `docs/graphs/*.rst` + `docs/old_graphs/index.rst` (anchored at - `utils.config.MAIN_FOLDER`), fetch sizes, report every row whose cell - disagrees with the stored object (or is missing), exit code 1 on any - problem; `--update`: fetch all sizes first, then rewrite the files and - print what changed. - -**Tests:** New `tests/utils/test_archive_sizes.py` — synthetic RST strings -only, no network: parser finds graph tables and skips non-graph tables; -`extract_url`; `update_table` inserts the column into a table that lacks it -and fixes wrong values in one that has it (idempotent second pass → 0 -changes); row/URL alignment on a multi-grammar table (3 grammar columns, like -`rdf.rst`). `fetch_sizes` tested with a local `http.server` serving HEAD -responses (or monkeypatched `_head_size`) — no external network. -**Docs:** none yet (the tool's docs page section lands in S6, together with -the populated tables it documents). +- Append the section at the end of each page (after the list-table), one + blank line between the table and the section header. +- Do NOT delete the `.inc` files or touch graph pages yet (S4) — the build + must stay green at every commit, and includes resolve until removed. -**Spec:** -- RST cell insertion preserves the exact indentation of the file - (` * - ` row starts, ` - ` continuation cells); the no-warnings docs - build is the safety net for malformed tables. -- Check mode output: one line per problem - (`:: : table says X, stored is Y`), then a summary; - exit 0 only when every row of every graph table matches S3. -- Update mode writes a file only if it changed; all fetches happen before any - write (a failed HEAD aborts the run with nothing written). - -### S4: Populate the Size (MB) column in all 9 tables - -**Code:** none (the change is produced by running the new tool — dogfooding). -**Tests:** `python utils/archive_sizes.py` (check mode) must report all 9 -tables in sync (167 rows) against live S3. -**Docs:** The 8 per-category tables + `docs/old_graphs/index.rst` gain the -`Size (MB)` column; one sentence added to the "Contents" section of -`docs/graphs/index.rst` describing the column (the download size of the -`.tar.gz` archive, in MB). +### S3: Add "Canonical grammars" section to c_alias_analysis, biological_uniprot, rdf -**Spec:** -- Run `python utils/archive_sizes.py --update` from the repo root; inspect - the diff: exactly one new header cell and one new cell per row in each of - the 9 tables, values matching the live S3 sizes fetched during planning. -- Re-run check mode → clean. Build the docs (no-warnings) to validate the - RST. - -### S5: Upload tool reports the computed size - -**Code:** `utils/upload_to_s3.py`: -- `upload_file()` — extend the existing `logging.info` with the verified size - in bytes; return type unchanged (`key`), so `migrate_gdrive_to_s3.py` is - untouched. -- `main()` — print the size in both units using `sizes.format_size_mb`: - `Uploaded FILE to s3://BUCKET/KEY (12345678 bytes, 11.79 MB)`. -**Tests:** Extend `tests/utils/test_upload_to_s3.py`: `test_main_uploads_file` -asserts the byte count and the formatted MB value in the output; a small-file -case exercises the `< 1 MB` formatting branch (`0.000 MB`). -**Docs:** `docs/utils.rst`, "Upload to Yandex S3" section — extend the -verification paragraph: the tool reports the verified size (bytes and MB), -which is the value for the `Size (MB)` column of the graph tables. +**Code:** n/a (docs-only). Modify `docs/graphs/c_alias_analysis.rst`, +`docs/graphs/biological_uniprot.rst`, `docs/graphs/rdf.rst`. +**Tests:** n/a — verified by the docs build (S6). +**Docs:** the 3 category pages gain a `Canonical grammars` section after the +graph table. **Spec:** -- The reported size is the *verified* stored size (the `head_object` - `ContentLength` that already must equal the local file size) — the same - number `archive_sizes.py` reads back from S3, so a new-graph row filled - from the upload output always matches check mode. - -### S6: Document the tool and the new-graph flow - -**Code:** none. -**Tests:** none (docs-only; docs build in S7). -**Docs:** -- `docs/utils.rst` — new "Archive sizes" section for `utils/archive_sizes.py` - (usage, check vs `--update`, what it covers: the 9 graph tables, URL keying, - all-or-nothing updates), placed after "Upload to Yandex S3". -- `.opencode/skills/add-graph/SKILL.md` — Documentation section gains the size - step: the upload tool reports the archive size; add the category-table row - with that `Size (MB)` value; run `python utils/archive_sizes.py --update` - before committing so every table row (including the new one) matches S3. -- `CHANGELOG.md` `[Unreleased] → Added`: one bullet for the `Size (MB)` column - in the website graph tables, one for the tooling (`upload_to_s3.py` reports - the verified size; new `utils/archive_sizes.py` keeps the column in sync). +- c_alias_analysis: verbatim from the inline section shared by its 20 graph + pages (the `.. note::` about `change_edges`, both grammar variants with the + `----` separator, Pyformlang blocks, `:ref:`c_alias`` cross-reference). +- biological_uniprot: verbatim from the inline section shared by its 10 + unigraph pages ("The grammar file is attached to the archive." + math). +- rdf: union — the 3 grammars shared by 19 pages (combined subClassOf+type, + subClassOf-only, type-only) plus the broaderTransitive grammar from + geospecies.rst, in that order, keeping the `----` separators and the + `:ref:`nested_parentheses`` cross-reference. + +### S4: Remove grammar sections from all 113 graph pages; delete the .inc files + +**Code:** n/a (docs-only). Modify all 113 `docs/graphs/data/*.rst` pages; +delete `docs/graphs/data/grammar_java_points_to.inc`, +`grammar_cpu17_field_sensitive_alias.inc`, +`grammar_cpu17_context_sensitive_data_flow.inc`, +`grammar_data_provenance.inc`, `grammar_name_resolution.inc`. +**Tests:** n/a — verified by the docs build (S6). +**Docs:** graph pages lose their trailing grammar section; no replacement +text (user decision). **Spec:** -- The skill stays a thin pointer: it names the step and the command, the - model (column semantics, formatting rule) lives in the docs. - -### S7: Quality gate, review, merge +- 64 pages carry the section inline (header at line start: `Canonical + grammars` or `Grammar`, section runs to EOF): delete from the header line + to EOF, leaving the file ending with the Edges Statistics table and a + single trailing newline. +- 49 pages end with a blank line + `.. include:: grammar_*.inc`: delete both + lines. +- Verify afterwards: no `include::` left in `docs/graphs/`, no page starts a + section with `^Canonical|^Grammar`, and the 5 `.inc` files are gone. +- `docs/old_graphs/` untouched. + +### S5: Update contribution templates, add-graph skill, graphs index note + +**Code:** n/a (docs-only). Modify +`.github/PULL_REQUEST_TEMPLATE/new_graph.md`, +`.github/ISSUE_TEMPLATE/graph-add-template.md`, +`.opencode/skills/add-graph/SKILL.md`, `docs/graphs/index.rst`. +**Tests:** n/a. +**Docs:** templates + skill + index note per spec. -**Code:** none (fixes only if the gate finds problems). -**Tests:** full quality gate per the `quality-gates` skill: `uv run pytest`, -ruff (check + format), `uv run ty check`, no-warnings docs build, linkcheck. -**Docs:** `tasks/tasks.md` — mark Task 40 `[done]` after the merge. +**Spec:** +- Both templates: add a `Category` row to the Info table — value is the + existing category name, or `new: `. +- Both templates: replace the "Canonical grammars" section with the three-case + structure: (1) graph for an existing category — name the grammar(s) from + the category's "Canonical grammars" section that apply; they become the + table column(s) filled in for the new row; no new grammar text. (2) New + grammar for an existing category — provide LaTeX + Pyformlang below; it is + added to the category page and a new column to its table. (3) Graph for a + new category — provide the canonical grammar(s) below; a new category page + is created with them. The LaTeX/Pyformlang placeholders apply to cases 2–3 + only. +- add-graph skill Documentation step: per-graph pages no longer carry a + grammar section; describe the three cases (row under an existing column / + add grammar + column to the category page / new category page with grammar, + table, and `docs/graphs/index.rst` registration). +- `docs/graphs/index.rst` "Contents" section: one sentence stating that + canonical grammars are documented on the category pages. + +### S6: Docs build verification + +**Code:** n/a. +**Tests:** full Sphinx build per the build-docs skill; zero warnings +(no-warnings policy); no new "not included in any toctree" warnings; spot-check +rendered HTML of the 8 category pages (section present, math rendered) and a +few graph pages (section gone). +**Docs:** n/a. **Spec:** -- Whole-repo code review per the `code-review` skill first; iterate to zero - findings. -- Rebase onto `dev`, fast-forward merge, delete the feature branch (per - `git-workflow`). No pushes. +- Build must exit clean under the project's no-warnings configuration. +- Grep the build log for `grammar_*.inc` (no unresolved includes) and for + dangling refs. diff --git a/tasks/tasks.md b/tasks/tasks.md index b0bcc259..b681b252 100644 --- a/tasks/tasks.md +++ b/tasks/tasks.md @@ -40,3 +40,4 @@ - [done] Task 38: We use mechanism to close issues automatically described here: https://github.blog/news-insights/product-news/closing-issues-via-commit-messages/ Improve imstructions to write respective commut message when task is link to issue. - [done] Task 39: Fix https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/94 - [done] Task 40: For the site, add archive sizes (size to download) to tables with graphs. Add one new column to each table (for each category). Choose one unit of neasure for all graphs (Kb, Mb or Gb). Moreover, improve tool that uploads new graph. It should compute archive size. When new raph added, table must be updated. So computed size used for it. **[USER GUIDANCE]**: "Include old graphs (Recommended)" / "Add a reusable utils script" +- [ ] Task 41: Analyze structure of the site. Looks like better place for canonical grammars description is category page, not graph. Because grammar canonical for category. **[USER GUIDANCE]**: "On issue and request teplamtes. If graph for existing category, then ok. But we can have at least two more options. Graph for new category. Then grammars should be provided. New grammar for existing category." / "Nothing (Recommended)" (graph pages keep no grammar section or pointer) / "Leave as-is (Recommended)" (docs/old_graphs legacy pages untouched) / "All 4 grammars (Recommended)" (rdf category page lists the union incl. broaderTransitive) / "Yes, add it (Recommended)" (Category row in both graph templates) From 52dd7fa4d626d8ae9ac23457dd1ac0b3cc1f0138 Mon Sep 17 00:00:00 2001 From: gsv Date: Fri, 18 Sep 2026 09:31:30 +0300 Subject: [PATCH 034/277] docs(41-S2): document the canonical grammars on the five .inc-based category pages Move the canonical grammar description from the per-graph pages to the category page, where it belongs: a grammar is canonical for the whole category, and repeating it on up to 21 graph pages is duplication. The text is moved verbatim from the .inc files that the graph pages include (the .inc files are removed in a later subtask), with the section heading normalized to 'Canonical grammars' across all category pages. Cross- references to the parameterized template pages under docs/grammars/ are kept, since they tie each concrete grammar to its template. --- docs/graphs/context_sensitive_data_flow.rst | 18 ++++++++++++++++ docs/graphs/data_provenance.rst | 23 +++++++++++++++++++++ docs/graphs/field_sensitive_alias.rst | 22 ++++++++++++++++++++ docs/graphs/java_points_to.rst | 12 +++++++++++ docs/graphs/name_resolution.rst | 16 ++++++++++++++ 5 files changed, 91 insertions(+) diff --git a/docs/graphs/context_sensitive_data_flow.rst b/docs/graphs/context_sensitive_data_flow.rst index 0eee69a0..280430ed 100644 --- a/docs/graphs/context_sensitive_data_flow.rst +++ b/docs/graphs/context_sensitive_data_flow.rst @@ -95,3 +95,21 @@ families), as in `"Taming Transitive Redundancy for Context-Free Language Reacha - 297504186 - 4.41 - `perlbench.tar.gz `_ 📥 + +Canonical grammars +------------------ + +Productions with index :math:`i` are duplicated for each call site in the analyzed program. +The start nonterminal is :math:`A`. + +.. math:: + + A \, \rightarrow \, A \, A \mid a \mid \varepsilon \, \\ + A \, \rightarrow \, call_i \, A \, ret_i \, \\ + +`Pyformlang CFG `_: + +.. code-block:: python + + A -> A A | a | epsilon + A -> call_i A ret_i diff --git a/docs/graphs/data_provenance.rst b/docs/graphs/data_provenance.rst index 9dfedcbd..c4520819 100644 --- a/docs/graphs/data_provenance.rst +++ b/docs/graphs/data_provenance.rst @@ -151,3 +151,26 @@ Python projects, following the W3C PROV model (``Entity``, ``Activity``, - 91350 - 1.56 - `airflow.tar.gz `_ 📥 + +Canonical grammars +------------------ + +The grammar file is attached to the archive. + +.. math:: + + S &\to Entity \quad Core \quad Entity \\ + Core &\to wasDerivedFrom \\ + &\mid wasDerivedFrom_{r} \\ + &\mid specializationOf \\ + &\mid specializationOf_{r} \\ + &\mid wasGeneratedBy \quad Activity \quad used \\ + &\mid used_{r} \quad Activity \quad wasGeneratedBy_{r} \\ + &\mid wasGeneratedBy \quad Activity \quad Core \\ + &\quad Activity \quad wasGeneratedBy_{r} \\ + &\mid used_{r} \quad Activity \quad Core \\ + &\quad Activity \quad used \\ + &\mid wasDerivedFrom \quad Entity \quad Core \\ + &\quad Entity \quad wasDerivedFrom_{r} \\ + &\mid specializationOf \quad Entity \quad Core \\ + &\quad Entity \quad specializationOf_{r} diff --git a/docs/graphs/field_sensitive_alias.rst b/docs/graphs/field_sensitive_alias.rst index f10cbe2d..adc91f95 100644 --- a/docs/graphs/field_sensitive_alias.rst +++ b/docs/graphs/field_sensitive_alias.rst @@ -95,3 +95,25 @@ field (the ``f_i`` family), as in `"Taming Transitive Redundancy for Context-Fre - 158255766 - 0.524 - `omnetpp_field_sensitive_alias.tar.gz `_ 📥 + +Canonical grammars +------------------ + +Productions with index :math:`i` are duplicated for each field number from the analyzed program classes. +The start nonterminal is :math:`V`. + +.. math:: + + M \, \rightarrow \, d \, V \, d \, \\ + V \, \rightarrow \, A \, V \, A \mid f_i \, V \, f_i \mid M \mid \varepsilon \, \\ + A \, \rightarrow \, a \, M? \mid \varepsilon \, \\ + A \, \rightarrow \, M? \, a \mid \varepsilon \, \\ + +`Pyformlang RSA `_: + +.. code-block:: text + + M -> d V d + V -> A V A | f_i V f_i | M | epsilon + A -> a M? | epsilon + A -> M? a | epsilon diff --git a/docs/graphs/java_points_to.rst b/docs/graphs/java_points_to.rst index 6ca95c56..5f607f87 100644 --- a/docs/graphs/java_points_to.rst +++ b/docs/graphs/java_points_to.rst @@ -173,3 +173,15 @@ calls, returns) together with their reverses. - 34451130 - 2.26 - `tradesoap.tar.gz `_ 📥 + +Canonical grammars +------------------ + +Grammars for the field-sensitive analysis of Java programs introduced in `"Giga-scale exhaustive points-to analysis for Java in under a minute" `_. +Template for these grammars is described on the :ref:`java_points-to` page. + +.. math:: + \textit{PointsTo} \, \rightarrow \, (\textit{assign} \mid \textit{load}_f \, \textit{Alias} \, \textit{store}_f)^{*} \, \textit{alloc} \, \\ + \textit{Alias} \, \rightarrow \, \textit{PointsTo} \, \textit{FlowsTo} \, \\ + \textit{FlowsTo} \, \rightarrow \, \overline{\textit{alloc}} \, (\overline{\textit{assign}} \mid \overline{\textit{store}_f} \, \textit{Alias} \, \overline{\textit{load}_f})^* \, \\ + \forall \, f \, \in \, Fields diff --git a/docs/graphs/name_resolution.rst b/docs/graphs/name_resolution.rst index 9bcd03e9..65524d8f 100644 --- a/docs/graphs/name_resolution.rst +++ b/docs/graphs/name_resolution.rst @@ -54,3 +54,19 @@ scopes. - not available - 11.27 - `libgdx.tar.gz `_ 📥 + +Canonical grammars +------------------ + +The grammar file is attached to the archive. + +.. math:: + + S &\to \varepsilon \\ + &\mid eps \quad S \\ + &\mid Q \quad S \\ + &\mid V \quad S \\ + S\#psh_{i} &\to psh_{i} \quad S \\ + S\#vpsh_{i} &\to vpsh_{i} \quad S \\ + V &\to S\#vpsh_{i} \quad vpp_{i} \\ + Q &\to S\#psh_{i} \quad pp_{i} From 546db11731aa5037f5735776bad5ffff31c81d9a Mon Sep 17 00:00:00 2001 From: gsv Date: Fri, 18 Sep 2026 09:32:30 +0300 Subject: [PATCH 035/277] docs(41-S3): document the canonical grammars on the remaining three category pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Complete the move of the canonical grammar descriptions to the category pages for the categories that carried them as copy-pasted inline sections instead of .inc includes: c_alias_analysis (both grammar variants plus the change_edges note, verbatim from the section shared by its 20 graph pages), biological_uniprot (verbatim from the section shared by its 10 unigraph pages), and rdf — where the category page gets the union of all four grammars: the three nested-parentheses variants shared by 19 graphs plus the broaderTransitive grammar that only geospecies uses, matching the table's existing broaderTransitive column. --- docs/graphs/biological_uniprot.rst | 16 +++++++++ docs/graphs/c_alias_analysis.rst | 48 ++++++++++++++++++++++++++ docs/graphs/rdf.rst | 54 ++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) diff --git a/docs/graphs/biological_uniprot.rst b/docs/graphs/biological_uniprot.rst index d8601e28..a6618de1 100644 --- a/docs/graphs/biological_uniprot.rst +++ b/docs/graphs/biological_uniprot.rst @@ -96,3 +96,19 @@ as in `"Subgraph queries by context-free grammars" `_ 📥 + +Canonical grammars +------------------ + +The grammar file is attached to the archive. + +.. math:: + + S &\to Seq \quad IsAssociated \quad IsSimilar \\ + Seq &\to IsSimilar \quad (codes\_for \quad IsSimilar)? \\ + IsSimilar &\to \varepsilon \\ + &\mid has \quad IsSimilar \quad has_{r} \\ + &\mid is\_homologous\_to \quad IsSimilar \quad is\_homologous\_to_{r} \quad IsSimilar \\ + &\mid belongs\_to \quad IsSimilar \quad belongs\_to_{r} \\ + &\mid participate\_in \quad IsSimilar \quad participate\_in_{r} \\ + IsAssociated &\to refers\_to \quad refers\_to_{r} diff --git a/docs/graphs/c_alias_analysis.rst b/docs/graphs/c_alias_analysis.rst index 595e6419..f7e13156 100644 --- a/docs/graphs/c_alias_analysis.rst +++ b/docs/graphs/c_alias_analysis.rst @@ -166,3 +166,51 @@ discovered for each program. - 16747731 - 59.99 - `kernel.tar.gz `_ 📥 + +Canonical grammars +------------------ + +.. note:: + + In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. + +Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. +Template for these grammars is described on the :ref:`c_alias` page. + +.. math:: + + S \, \rightarrow \, \overline{d} \, V \, d \, \\ + V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ + V_1 \, \rightarrow \, \varepsilon \, \\ + V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ + V_2 \, \rightarrow \, \varepsilon \, \\ + V_2 \, \rightarrow \, S \, \\ + V_3 \, \rightarrow \, \varepsilon \, \\ + V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ + +`Pyformlang CFG `_: + +.. code-block:: python + + S -> d_r V d + V -> V1 V2 V3 + V1 -> epsilon + V1 -> V2 a_r V1 + V2 -> epsilon + V2 -> S + V3 -> epsilon + V3 -> a V2 V3 + +---- + +.. math:: + + S \, \rightarrow \, \overline{d} \, V \, d \, \\ + V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ + +`Pyformlang RSA `_: + +.. code-block:: python + + S -> d_r V d + V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/rdf.rst b/docs/graphs/rdf.rst index da93a376..33374047 100644 --- a/docs/graphs/rdf.rst +++ b/docs/graphs/rdf.rst @@ -228,3 +228,57 @@ queries over RDF as in `"Context-Free Path Queries on RDF Graphs" `_ 📥 + +Canonical grammars +------------------ + +Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. +Template for these grammars is described on the :ref:`nested_parentheses` page. + +.. math:: + + S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ + S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ + +`Pyformlang CFG `_: + +.. code-block:: python + + S -> subClassOf_r S subClassOf | subClassOf_r subClassOf + S -> type_r S type | type_r type + +---- + +.. math:: + + S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ + +`Pyformlang CFG `_: + +.. code-block:: python + + S -> subClassOf_r S subClassOf | subClassOf_r subClassOf + +---- + +.. math:: + + S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ + +`Pyformlang CFG `_: + +.. code-block:: python + + S -> type_r S type | type_r type + +---- + +.. math:: + + S \, \rightarrow \, broaderTransitive \, S \, \overline{broaderTransitive} \, \mid \, broaderTransitive \, \overline{broaderTransitive} \, \\ + +`Pyformlang CFG `_: + +.. code-block:: python + + S -> broaderTransitive S broaderTransitive_r | broaderTransitive broaderTransitive_r From 1ee9f3013deb9a21ddaafd7c0cf81e8cd5b4a6fc Mon Sep 17 00:00:00 2001 From: gsv Date: Fri, 18 Sep 2026 09:33:16 +0300 Subject: [PATCH 036/277] docs(41-S4): drop the per-graph grammar sections now that categories document them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The canonical grammars live on the category pages since the previous two subtasks, so the per-graph copies are pure duplication: remove the trailing grammar section from all 113 graph pages (64 copy-pasted inline sections and 49 .. include:: directives) and delete the five grammar_*.inc files they pulled in. Graph pages keep nothing in its place — the category page is the parent in the navigation, one click away. docs/old_graphs is intentionally untouched: it is a legacy orphan list without category structure. --- docs/graphs/data/apache.rst | 49 ----------------- docs/graphs/data/arch.rst | 49 ----------------- docs/graphs/data/atom.rst | 43 --------------- docs/graphs/data/avrora.rst | 12 ---- docs/graphs/data/batik.rst | 12 ---- docs/graphs/data/biomedical.rst | 43 --------------- docs/graphs/data/block.rst | 49 ----------------- docs/graphs/data/bzip.rst | 49 ----------------- docs/graphs/data/cactus.rst | 2 - .../data/cactus_field_sensitive_alias.rst | 2 - docs/graphs/data/commons_io.rst | 2 - docs/graphs/data/commons_lang3.rst | 2 - docs/graphs/data/core.rst | 43 --------------- docs/graphs/data/crypto.rst | 49 ----------------- docs/graphs/data/drivers.rst | 49 ----------------- docs/graphs/data/eclass.rst | 43 --------------- docs/graphs/data/eclipse.rst | 12 ---- docs/graphs/data/enzyme.rst | 43 --------------- docs/graphs/data/foaf.rst | 43 --------------- docs/graphs/data/fop.rst | 12 ---- docs/graphs/data/fs.rst | 49 ----------------- docs/graphs/data/funding.rst | 43 --------------- docs/graphs/data/generations.rst | 43 --------------- docs/graphs/data/geospecies.rst | 55 ------------------- docs/graphs/data/go.rst | 43 --------------- docs/graphs/data/go_hierarchy.rst | 43 --------------- ...mmar_cpu17_context_sensitive_data_flow.inc | 17 ------ .../grammar_cpu17_field_sensitive_alias.inc | 21 ------- docs/graphs/data/grammar_data_provenance.inc | 22 -------- docs/graphs/data/grammar_java_points_to.inc | 11 ---- docs/graphs/data/grammar_name_resolution.inc | 15 ----- docs/graphs/data/gson.rst | 2 - docs/graphs/data/guava.rst | 2 - docs/graphs/data/gzip.rst | 49 ----------------- docs/graphs/data/h2.rst | 12 ---- docs/graphs/data/imagick.rst | 2 - .../data/imagick_field_sensitive_alias.rst | 2 - docs/graphs/data/init.rst | 49 ----------------- docs/graphs/data/ipc.rst | 49 ----------------- docs/graphs/data/jackson.rst | 2 - docs/graphs/data/junit5.rst | 2 - docs/graphs/data/jython.rst | 12 ---- docs/graphs/data/kernel.rst | 49 ----------------- docs/graphs/data/leela.rst | 2 - .../data/leela_field_sensitive_alias.rst | 2 - docs/graphs/data/lib.rst | 49 ----------------- docs/graphs/data/ls.rst | 49 ----------------- docs/graphs/data/luindex.rst | 12 ---- docs/graphs/data/lusearch.rst | 12 ---- docs/graphs/data/mm.rst | 49 ----------------- docs/graphs/data/mockito.rst | 2 - docs/graphs/data/nab.rst | 2 - .../graphs/data/nab_field_sensitive_alias.rst | 2 - docs/graphs/data/name_resolution_jiaozi.rst | 2 - docs/graphs/data/name_resolution_jsonpath.rst | 2 - docs/graphs/data/name_resolution_libgdx.rst | 2 - ...ame_resolution_shattered_pixel_dungeon.rst | 2 - docs/graphs/data/net.rst | 49 ----------------- docs/graphs/data/omnetpp.rst | 2 - .../data/omnetpp_field_sensitive_alias.rst | 2 - docs/graphs/data/parest.rst | 2 - .../data/parest_field_sensitive_alias.rst | 2 - docs/graphs/data/pathways.rst | 43 --------------- docs/graphs/data/people.rst | 43 --------------- docs/graphs/data/perlbench.rst | 2 - .../data/perlbench_field_sensitive_alias.rst | 2 - docs/graphs/data/pizza.rst | 43 --------------- docs/graphs/data/pmd.rst | 12 ---- docs/graphs/data/postgre.rst | 49 ----------------- docs/graphs/data/povray.rst | 2 - .../data/povray_field_sensitive_alias.rst | 2 - docs/graphs/data/pr.rst | 49 ----------------- docs/graphs/data/provenance_airflow.rst | 2 - docs/graphs/data/provenance_celery.rst | 2 - docs/graphs/data/provenance_click.rst | 2 - docs/graphs/data/provenance_django.rst | 2 - docs/graphs/data/provenance_fastapi.rst | 2 - docs/graphs/data/provenance_flask.rst | 2 - docs/graphs/data/provenance_httpx.rst | 2 - docs/graphs/data/provenance_itsdangerous.rst | 2 - docs/graphs/data/provenance_jinja.rst | 2 - docs/graphs/data/provenance_pandas.rst | 2 - docs/graphs/data/provenance_pluggy.rst | 2 - docs/graphs/data/provenance_requests.rst | 2 - docs/graphs/data/provenance_sampleproject.rst | 2 - docs/graphs/data/provenance_scikit_learn.rst | 2 - docs/graphs/data/provenance_sphinx.rst | 2 - docs/graphs/data/provenance_superset.rst | 2 - .../data/provenance_wikipedia_provenance.rst | 2 - docs/graphs/data/provenance_zulip.rst | 2 - docs/graphs/data/security.rst | 49 ----------------- docs/graphs/data/skos.rst | 43 --------------- docs/graphs/data/sound.rst | 49 ----------------- docs/graphs/data/sunflow.rst | 12 ---- docs/graphs/data/taxonomy.rst | 43 --------------- docs/graphs/data/taxonomy_hierarchy.rst | 43 --------------- docs/graphs/data/tomcat.rst | 12 ---- docs/graphs/data/tradebeans.rst | 12 ---- docs/graphs/data/tradesoap.rst | 12 ---- docs/graphs/data/travel.rst | 43 --------------- docs/graphs/data/unigraph_1.rst | 16 ------ docs/graphs/data/unigraph_10.rst | 16 ------ docs/graphs/data/unigraph_2.rst | 16 ------ docs/graphs/data/unigraph_3.rst | 16 ------ docs/graphs/data/unigraph_4.rst | 16 ------ docs/graphs/data/unigraph_5.rst | 16 ------ docs/graphs/data/unigraph_6.rst | 16 ------ docs/graphs/data/unigraph_7.rst | 16 ------ docs/graphs/data/unigraph_8.rst | 16 ------ docs/graphs/data/unigraph_9.rst | 16 ------ docs/graphs/data/univ.rst | 43 --------------- docs/graphs/data/wc.rst | 49 ----------------- docs/graphs/data/wine.rst | 43 --------------- docs/graphs/data/x264.rst | 2 - .../data/x264_field_sensitive_alias.rst | 2 - docs/graphs/data/xalan.rst | 12 ---- docs/graphs/data/xz.rst | 2 - docs/graphs/data/xz_field_sensitive_alias.rst | 2 - 118 files changed, 2364 deletions(-) delete mode 100644 docs/graphs/data/grammar_cpu17_context_sensitive_data_flow.inc delete mode 100644 docs/graphs/data/grammar_cpu17_field_sensitive_alias.inc delete mode 100644 docs/graphs/data/grammar_data_provenance.inc delete mode 100644 docs/graphs/data/grammar_java_points_to.inc delete mode 100644 docs/graphs/data/grammar_name_resolution.inc diff --git a/docs/graphs/data/apache.rst b/docs/graphs/data/apache.rst index a05abf17..64254d31 100644 --- a/docs/graphs/data/apache.rst +++ b/docs/graphs/data/apache.rst @@ -45,52 +45,3 @@ Edges Statistics - 1147612 * - a - 362799 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/arch.rst b/docs/graphs/data/arch.rst index 5483e88f..a0202330 100644 --- a/docs/graphs/data/arch.rst +++ b/docs/graphs/data/arch.rst @@ -45,52 +45,3 @@ Edges Statistics - 2298947 * - a - 671295 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/atom.rst b/docs/graphs/data/atom.rst index ba0d2ee6..0f98826f 100644 --- a/docs/graphs/data/atom.rst +++ b/docs/graphs/data/atom.rst @@ -75,46 +75,3 @@ Edges Statistics - 1 * - format - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/avrora.rst b/docs/graphs/data/avrora.rst index 881c1cfa..d6d596c5 100644 --- a/docs/graphs/data/avrora.rst +++ b/docs/graphs/data/avrora.rst @@ -55,15 +55,3 @@ Edges Statistics - 3684 * - :math:`\textit{store}_f` - 977 - -Canonical grammars ------------------- - -Grammars for the field-sensitive analysis of Java programs introduced in `"Giga-scale exhaustive points-to analysis for Java in under a minute" `_. -Template for these grammars is described on the :ref:`java_points-to` page. - -.. math:: - \textit{PointsTo} \, \rightarrow \, (\textit{assign} \mid \textit{load}_f \, \textit{Alias} \, \textit{store}_f)^{*} \, \textit{alloc} \, \\ - \textit{Alias} \, \rightarrow \, \textit{PointsTo} \, \textit{FlowsTo} \, \\ - \textit{FlowsTo} \, \rightarrow \, \overline{\textit{alloc}} \, (\overline{\textit{assign}} \mid \overline{\textit{store}_f} \, \textit{Alias} \, \overline{\textit{load}_f})^* \, \\ - \forall \, f \, \in \, Fields diff --git a/docs/graphs/data/batik.rst b/docs/graphs/data/batik.rst index 36fb3529..768c89ab 100644 --- a/docs/graphs/data/batik.rst +++ b/docs/graphs/data/batik.rst @@ -55,15 +55,3 @@ Edges Statistics - 7176 * - :math:`\textit{store}_f` - 1686 - -Canonical grammars ------------------- - -Grammars for the field-sensitive analysis of Java programs introduced in `"Giga-scale exhaustive points-to analysis for Java in under a minute" `_. -Template for these grammars is described on the :ref:`java_points-to` page. - -.. math:: - \textit{PointsTo} \, \rightarrow \, (\textit{assign} \mid \textit{load}_f \, \textit{Alias} \, \textit{store}_f)^{*} \, \textit{alloc} \, \\ - \textit{Alias} \, \rightarrow \, \textit{PointsTo} \, \textit{FlowsTo} \, \\ - \textit{FlowsTo} \, \rightarrow \, \overline{\textit{alloc}} \, (\overline{\textit{assign}} \mid \overline{\textit{store}_f} \, \textit{Alias} \, \overline{\textit{load}_f})^* \, \\ - \forall \, f \, \in \, Fields diff --git a/docs/graphs/data/biomedical.rst b/docs/graphs/data/biomedical.rst index d584bb46..91d09bb3 100644 --- a/docs/graphs/data/biomedical.rst +++ b/docs/graphs/data/biomedical.rst @@ -61,46 +61,3 @@ Edges Statistics - 1 * - creator - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/block.rst b/docs/graphs/data/block.rst index d6be1e97..a795ff3d 100644 --- a/docs/graphs/data/block.rst +++ b/docs/graphs/data/block.rst @@ -45,52 +45,3 @@ Edges Statistics - 2282155 * - a - 669238 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/bzip.rst b/docs/graphs/data/bzip.rst index c07d031f..232978dc 100644 --- a/docs/graphs/data/bzip.rst +++ b/docs/graphs/data/bzip.rst @@ -47,52 +47,3 @@ Edges Statistics - 297 * - a - 259 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/cactus.rst b/docs/graphs/data/cactus.rst index c1328ec3..919e6bde 100644 --- a/docs/graphs/data/cactus.rst +++ b/docs/graphs/data/cactus.rst @@ -47,5 +47,3 @@ Edges Statistics - 123500 * - :math:`ret_i` - 63671 - -.. include:: grammar_cpu17_context_sensitive_data_flow.inc diff --git a/docs/graphs/data/cactus_field_sensitive_alias.rst b/docs/graphs/data/cactus_field_sensitive_alias.rst index 058cc66d..276c8efe 100644 --- a/docs/graphs/data/cactus_field_sensitive_alias.rst +++ b/docs/graphs/data/cactus_field_sensitive_alias.rst @@ -53,5 +53,3 @@ Edges Statistics - 10790 * - :math:`fbar_i` - 10790 - -.. include:: grammar_cpu17_field_sensitive_alias.inc diff --git a/docs/graphs/data/commons_io.rst b/docs/graphs/data/commons_io.rst index d766e177..0111d409 100644 --- a/docs/graphs/data/commons_io.rst +++ b/docs/graphs/data/commons_io.rst @@ -59,5 +59,3 @@ Edges Statistics - 1247 * - :math:`\overline{\textit{store}_i}` - 1247 - -.. include:: grammar_java_points_to.inc diff --git a/docs/graphs/data/commons_lang3.rst b/docs/graphs/data/commons_lang3.rst index d1c50aba..b4863d3c 100644 --- a/docs/graphs/data/commons_lang3.rst +++ b/docs/graphs/data/commons_lang3.rst @@ -59,5 +59,3 @@ Edges Statistics - 2719 * - :math:`\overline{\textit{store}_i}` - 2719 - -.. include:: grammar_java_points_to.inc diff --git a/docs/graphs/data/core.rst b/docs/graphs/data/core.rst index 99b5ba2c..34d3d87a 100644 --- a/docs/graphs/data/core.rst +++ b/docs/graphs/data/core.rst @@ -105,46 +105,3 @@ Edges Statistics - 1 * - minCardinality - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/crypto.rst b/docs/graphs/data/crypto.rst index 51289462..435e4329 100644 --- a/docs/graphs/data/crypto.rst +++ b/docs/graphs/data/crypto.rst @@ -45,52 +45,3 @@ Edges Statistics - 2309979 * - a - 678408 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/drivers.rst b/docs/graphs/data/drivers.rst index e79a4a2c..04d704cd 100644 --- a/docs/graphs/data/drivers.rst +++ b/docs/graphs/data/drivers.rst @@ -45,52 +45,3 @@ Edges Statistics - 2849201 * - a - 858568 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/eclass.rst b/docs/graphs/data/eclass.rst index 407b088f..7d1e6fe6 100644 --- a/docs/graphs/data/eclass.rst +++ b/docs/graphs/data/eclass.rst @@ -63,46 +63,3 @@ Edges Statistics - 1 * - imports - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/eclipse.rst b/docs/graphs/data/eclipse.rst index 003e145a..67c6519e 100644 --- a/docs/graphs/data/eclipse.rst +++ b/docs/graphs/data/eclipse.rst @@ -55,15 +55,3 @@ Edges Statistics - 4575 * - :math:`\textit{store}_f` - 961 - -Canonical grammars ------------------- - -Grammars for the field-sensitive analysis of Java programs introduced in `"Giga-scale exhaustive points-to analysis for Java in under a minute" `_. -Template for these grammars is described on the :ref:`java_points-to` page. - -.. math:: - \textit{PointsTo} \, \rightarrow \, (\textit{assign} \mid \textit{load}_f \, \textit{Alias} \, \textit{store}_f)^{*} \, \textit{alloc} \, \\ - \textit{Alias} \, \rightarrow \, \textit{PointsTo} \, \textit{FlowsTo} \, \\ - \textit{FlowsTo} \, \rightarrow \, \overline{\textit{alloc}} \, (\overline{\textit{assign}} \mid \overline{\textit{store}_f} \, \textit{Alias} \, \overline{\textit{load}_f})^* \, \\ - \forall \, f \, \in \, Fields diff --git a/docs/graphs/data/enzyme.rst b/docs/graphs/data/enzyme.rst index 33916b61..f8f3c6d3 100644 --- a/docs/graphs/data/enzyme.rst +++ b/docs/graphs/data/enzyme.rst @@ -71,46 +71,3 @@ Edges Statistics - 1356 * - imports - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/foaf.rst b/docs/graphs/data/foaf.rst index 71cd9af8..a88677d8 100644 --- a/docs/graphs/data/foaf.rst +++ b/docs/graphs/data/foaf.rst @@ -71,46 +71,3 @@ Edges Statistics - 1 * - equivalentProperty - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/fop.rst b/docs/graphs/data/fop.rst index 9c7aac87..01b2c5b7 100644 --- a/docs/graphs/data/fop.rst +++ b/docs/graphs/data/fop.rst @@ -55,15 +55,3 @@ Edges Statistics - 7212 * - :math:`\textit{store}_f` - 1992 - -Canonical grammars ------------------- - -Grammars for the field-sensitive analysis of Java programs introduced in `"Giga-scale exhaustive points-to analysis for Java in under a minute" `_. -Template for these grammars is described on the :ref:`java_points-to` page. - -.. math:: - \textit{PointsTo} \, \rightarrow \, (\textit{assign} \mid \textit{load}_f \, \textit{Alias} \, \textit{store}_f)^{*} \, \textit{alloc} \, \\ - \textit{Alias} \, \rightarrow \, \textit{PointsTo} \, \textit{FlowsTo} \, \\ - \textit{FlowsTo} \, \rightarrow \, \overline{\textit{alloc}} \, (\overline{\textit{assign}} \mid \overline{\textit{store}_f} \, \textit{Alias} \, \overline{\textit{load}_f})^* \, \\ - \forall \, f \, \in \, Fields diff --git a/docs/graphs/data/fs.rst b/docs/graphs/data/fs.rst index a8c6e343..c013d1f8 100644 --- a/docs/graphs/data/fs.rst +++ b/docs/graphs/data/fs.rst @@ -45,52 +45,3 @@ Edges Statistics - 2784943 * - a - 824430 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/funding.rst b/docs/graphs/data/funding.rst index bb88ae30..bbd21b51 100644 --- a/docs/graphs/data/funding.rst +++ b/docs/graphs/data/funding.rst @@ -83,46 +83,3 @@ Edges Statistics - 1 * - seeAlso - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/generations.rst b/docs/graphs/data/generations.rst index 2df8ad8d..7798f46a 100644 --- a/docs/graphs/data/generations.rst +++ b/docs/graphs/data/generations.rst @@ -77,46 +77,3 @@ Edges Statistics - 1 * - oneOf - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/geospecies.rst b/docs/graphs/data/geospecies.rst index 5db3a427..33d2f82b 100644 --- a/docs/graphs/data/geospecies.rst +++ b/docs/graphs/data/geospecies.rst @@ -279,58 +279,3 @@ Edges Statistics - 1 * - value - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, broaderTransitive \, S \, \overline{broaderTransitive} \, \mid \, broaderTransitive \, \overline{broaderTransitive} \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> broaderTransitive S broaderTransitive_r | broaderTransitive broaderTransitive_r diff --git a/docs/graphs/data/go.rst b/docs/graphs/data/go.rst index ae649a37..f43c26fa 100644 --- a/docs/graphs/data/go.rst +++ b/docs/graphs/data/go.rst @@ -137,46 +137,3 @@ Edges Statistics - 1 * - is_class_level - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/go_hierarchy.rst b/docs/graphs/data/go_hierarchy.rst index 973a8d85..bb4e8b05 100644 --- a/docs/graphs/data/go_hierarchy.rst +++ b/docs/graphs/data/go_hierarchy.rst @@ -45,46 +45,3 @@ Edges Statistics - Num Edge Label * - subClassOf - 490109 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/grammar_cpu17_context_sensitive_data_flow.inc b/docs/graphs/data/grammar_cpu17_context_sensitive_data_flow.inc deleted file mode 100644 index 0642b50d..00000000 --- a/docs/graphs/data/grammar_cpu17_context_sensitive_data_flow.inc +++ /dev/null @@ -1,17 +0,0 @@ -Canonical Grammar ------------------ - -Productions with index :math:`i` are duplicated for each call site in the analyzed program. -The start nonterminal is :math:`A`. - -.. math:: - - A \, \rightarrow \, A \, A \mid a \mid \varepsilon \, \\ - A \, \rightarrow \, call_i \, A \, ret_i \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - A -> A A | a | epsilon - A -> call_i A ret_i diff --git a/docs/graphs/data/grammar_cpu17_field_sensitive_alias.inc b/docs/graphs/data/grammar_cpu17_field_sensitive_alias.inc deleted file mode 100644 index 7620f318..00000000 --- a/docs/graphs/data/grammar_cpu17_field_sensitive_alias.inc +++ /dev/null @@ -1,21 +0,0 @@ -Canonical Grammar ------------------ - -Productions with index :math:`i` are duplicated for each field number from the analyzed program classes. -The start nonterminal is :math:`V`. - -.. math:: - - M \, \rightarrow \, d \, V \, d \, \\ - V \, \rightarrow \, A \, V \, A \mid f_i \, V \, f_i \mid M \mid \varepsilon \, \\ - A \, \rightarrow \, a \, M? \mid \varepsilon \, \\ - A \, \rightarrow \, M? \, a \mid \varepsilon \, \\ - -`Pyformlang RSA `_: - -.. code-block:: text - - M -> d V d - V -> A V A | f_i V f_i | M | epsilon - A -> a M? | epsilon - A -> M? a | epsilon diff --git a/docs/graphs/data/grammar_data_provenance.inc b/docs/graphs/data/grammar_data_provenance.inc deleted file mode 100644 index 5a4625c8..00000000 --- a/docs/graphs/data/grammar_data_provenance.inc +++ /dev/null @@ -1,22 +0,0 @@ -Grammar -------- - -The grammar file is attached to the archive. - -.. math:: - - S &\to Entity \quad Core \quad Entity \\ - Core &\to wasDerivedFrom \\ - &\mid wasDerivedFrom_{r} \\ - &\mid specializationOf \\ - &\mid specializationOf_{r} \\ - &\mid wasGeneratedBy \quad Activity \quad used \\ - &\mid used_{r} \quad Activity \quad wasGeneratedBy_{r} \\ - &\mid wasGeneratedBy \quad Activity \quad Core \\ - &\quad Activity \quad wasGeneratedBy_{r} \\ - &\mid used_{r} \quad Activity \quad Core \\ - &\quad Activity \quad used \\ - &\mid wasDerivedFrom \quad Entity \quad Core \\ - &\quad Entity \quad wasDerivedFrom_{r} \\ - &\mid specializationOf \quad Entity \quad Core \\ - &\quad Entity \quad specializationOf_{r} diff --git a/docs/graphs/data/grammar_java_points_to.inc b/docs/graphs/data/grammar_java_points_to.inc deleted file mode 100644 index 1f5adad2..00000000 --- a/docs/graphs/data/grammar_java_points_to.inc +++ /dev/null @@ -1,11 +0,0 @@ -Canonical grammars ------------------- - -Grammars for the field-sensitive analysis of Java programs introduced in `"Giga-scale exhaustive points-to analysis for Java in under a minute" `_. -Template for these grammars is described on the :ref:`java_points-to` page. - -.. math:: - \textit{PointsTo} \, \rightarrow \, (\textit{assign} \mid \textit{load}_f \, \textit{Alias} \, \textit{store}_f)^{*} \, \textit{alloc} \, \\ - \textit{Alias} \, \rightarrow \, \textit{PointsTo} \, \textit{FlowsTo} \, \\ - \textit{FlowsTo} \, \rightarrow \, \overline{\textit{alloc}} \, (\overline{\textit{assign}} \mid \overline{\textit{store}_f} \, \textit{Alias} \, \overline{\textit{load}_f})^* \, \\ - \forall \, f \, \in \, Fields diff --git a/docs/graphs/data/grammar_name_resolution.inc b/docs/graphs/data/grammar_name_resolution.inc deleted file mode 100644 index 577dd274..00000000 --- a/docs/graphs/data/grammar_name_resolution.inc +++ /dev/null @@ -1,15 +0,0 @@ -Grammar -------- - -The grammar file is attached to the archive. - -.. math:: - - S &\to \varepsilon \\ - &\mid eps \quad S \\ - &\mid Q \quad S \\ - &\mid V \quad S \\ - S\#psh_{i} &\to psh_{i} \quad S \\ - S\#vpsh_{i} &\to vpsh_{i} \quad S \\ - V &\to S\#vpsh_{i} \quad vpp_{i} \\ - Q &\to S\#psh_{i} \quad pp_{i} diff --git a/docs/graphs/data/gson.rst b/docs/graphs/data/gson.rst index 8718f597..283eb332 100644 --- a/docs/graphs/data/gson.rst +++ b/docs/graphs/data/gson.rst @@ -59,5 +59,3 @@ Edges Statistics - 798 * - :math:`\overline{\textit{store}_i}` - 798 - -.. include:: grammar_java_points_to.inc diff --git a/docs/graphs/data/guava.rst b/docs/graphs/data/guava.rst index 473c08bd..a8203aa7 100644 --- a/docs/graphs/data/guava.rst +++ b/docs/graphs/data/guava.rst @@ -59,5 +59,3 @@ Edges Statistics - 7106 * - :math:`\overline{\textit{store}_i}` - 7106 - -.. include:: grammar_java_points_to.inc diff --git a/docs/graphs/data/gzip.rst b/docs/graphs/data/gzip.rst index 0170ab75..0c0b4309 100644 --- a/docs/graphs/data/gzip.rst +++ b/docs/graphs/data/gzip.rst @@ -47,52 +47,3 @@ Edges Statistics - 1218 * - a - 1075 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/h2.rst b/docs/graphs/data/h2.rst index 58d72a87..a7732aa6 100644 --- a/docs/graphs/data/h2.rst +++ b/docs/graphs/data/h2.rst @@ -55,15 +55,3 @@ Edges Statistics - 6709 * - :math:`\textit{store}_f` - 1243 - -Canonical grammars ------------------- - -Grammars for the field-sensitive analysis of Java programs introduced in `"Giga-scale exhaustive points-to analysis for Java in under a minute" `_. -Template for these grammars is described on the :ref:`java_points-to` page. - -.. math:: - \textit{PointsTo} \, \rightarrow \, (\textit{assign} \mid \textit{load}_f \, \textit{Alias} \, \textit{store}_f)^{*} \, \textit{alloc} \, \\ - \textit{Alias} \, \rightarrow \, \textit{PointsTo} \, \textit{FlowsTo} \, \\ - \textit{FlowsTo} \, \rightarrow \, \overline{\textit{alloc}} \, (\overline{\textit{assign}} \mid \overline{\textit{store}_f} \, \textit{Alias} \, \overline{\textit{load}_f})^* \, \\ - \forall \, f \, \in \, Fields diff --git a/docs/graphs/data/imagick.rst b/docs/graphs/data/imagick.rst index f94394e4..bacfa2f4 100644 --- a/docs/graphs/data/imagick.rst +++ b/docs/graphs/data/imagick.rst @@ -47,5 +47,3 @@ Edges Statistics - 49007 * - :math:`ret_i` - 23610 - -.. include:: grammar_cpu17_context_sensitive_data_flow.inc diff --git a/docs/graphs/data/imagick_field_sensitive_alias.rst b/docs/graphs/data/imagick_field_sensitive_alias.rst index 7c6057f2..caac8952 100644 --- a/docs/graphs/data/imagick_field_sensitive_alias.rst +++ b/docs/graphs/data/imagick_field_sensitive_alias.rst @@ -53,5 +53,3 @@ Edges Statistics - 26813 * - :math:`fbar_i` - 26813 - -.. include:: grammar_cpu17_field_sensitive_alias.inc diff --git a/docs/graphs/data/init.rst b/docs/graphs/data/init.rst index c9bcafad..25024d39 100644 --- a/docs/graphs/data/init.rst +++ b/docs/graphs/data/init.rst @@ -45,52 +45,3 @@ Edges Statistics - 1630815 * - a - 481994 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/ipc.rst b/docs/graphs/data/ipc.rst index 1875919d..16dc523a 100644 --- a/docs/graphs/data/ipc.rst +++ b/docs/graphs/data/ipc.rst @@ -45,52 +45,3 @@ Edges Statistics - 2267347 * - a - 664151 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/jackson.rst b/docs/graphs/data/jackson.rst index 861b3c0a..771631e0 100644 --- a/docs/graphs/data/jackson.rst +++ b/docs/graphs/data/jackson.rst @@ -59,5 +59,3 @@ Edges Statistics - 11509 * - :math:`\overline{\textit{store}_i}` - 11509 - -.. include:: grammar_java_points_to.inc diff --git a/docs/graphs/data/junit5.rst b/docs/graphs/data/junit5.rst index 9b610b9f..9be935e7 100644 --- a/docs/graphs/data/junit5.rst +++ b/docs/graphs/data/junit5.rst @@ -59,5 +59,3 @@ Edges Statistics - 3070 * - :math:`\overline{\textit{store}_i}` - 3070 - -.. include:: grammar_java_points_to.inc diff --git a/docs/graphs/data/jython.rst b/docs/graphs/data/jython.rst index 039be4f8..fd6b165c 100644 --- a/docs/graphs/data/jython.rst +++ b/docs/graphs/data/jython.rst @@ -55,15 +55,3 @@ Edges Statistics - 14685 * - :math:`\textit{store}_f` - 4173 - -Canonical grammars ------------------- - -Grammars for the field-sensitive analysis of Java programs introduced in `"Giga-scale exhaustive points-to analysis for Java in under a minute" `_. -Template for these grammars is described on the :ref:`java_points-to` page. - -.. math:: - \textit{PointsTo} \, \rightarrow \, (\textit{assign} \mid \textit{load}_f \, \textit{Alias} \, \textit{store}_f)^{*} \, \textit{alloc} \, \\ - \textit{Alias} \, \rightarrow \, \textit{PointsTo} \, \textit{FlowsTo} \, \\ - \textit{FlowsTo} \, \rightarrow \, \overline{\textit{alloc}} \, (\overline{\textit{assign}} \mid \overline{\textit{store}_f} \, \textit{Alias} \, \overline{\textit{load}_f})^* \, \\ - \forall \, f \, \in \, Fields diff --git a/docs/graphs/data/kernel.rst b/docs/graphs/data/kernel.rst index 35e931e3..2900e675 100644 --- a/docs/graphs/data/kernel.rst +++ b/docs/graphs/data/kernel.rst @@ -45,52 +45,3 @@ Edges Statistics - 7502955 * - a - 1981258 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/leela.rst b/docs/graphs/data/leela.rst index 7c96431e..bbb2e845 100644 --- a/docs/graphs/data/leela.rst +++ b/docs/graphs/data/leela.rst @@ -48,5 +48,3 @@ Edges Statistics - 3595 * - :math:`ret_i` - 2069 - -.. include:: grammar_cpu17_context_sensitive_data_flow.inc diff --git a/docs/graphs/data/leela_field_sensitive_alias.rst b/docs/graphs/data/leela_field_sensitive_alias.rst index 2b5a088d..c3fa5048 100644 --- a/docs/graphs/data/leela_field_sensitive_alias.rst +++ b/docs/graphs/data/leela_field_sensitive_alias.rst @@ -53,5 +53,3 @@ Edges Statistics - 3856 * - :math:`fbar_i` - 3856 - -.. include:: grammar_cpu17_field_sensitive_alias.inc diff --git a/docs/graphs/data/lib.rst b/docs/graphs/data/lib.rst index ca1db3a5..066c9ef4 100644 --- a/docs/graphs/data/lib.rst +++ b/docs/graphs/data/lib.rst @@ -45,52 +45,3 @@ Edges Statistics - 2267569 * - a - 664311 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/ls.rst b/docs/graphs/data/ls.rst index a50753eb..e3f789a6 100644 --- a/docs/graphs/data/ls.rst +++ b/docs/graphs/data/ls.rst @@ -47,52 +47,3 @@ Edges Statistics - 750 * - a - 703 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/luindex.rst b/docs/graphs/data/luindex.rst index fba9bb0a..e6046885 100644 --- a/docs/graphs/data/luindex.rst +++ b/docs/graphs/data/luindex.rst @@ -55,15 +55,3 @@ Edges Statistics - 3340 * - :math:`\textit{store}_f` - 859 - -Canonical grammars ------------------- - -Grammars for the field-sensitive analysis of Java programs introduced in `"Giga-scale exhaustive points-to analysis for Java in under a minute" `_. -Template for these grammars is described on the :ref:`java_points-to` page. - -.. math:: - \textit{PointsTo} \, \rightarrow \, (\textit{assign} \mid \textit{load}_f \, \textit{Alias} \, \textit{store}_f)^{*} \, \textit{alloc} \, \\ - \textit{Alias} \, \rightarrow \, \textit{PointsTo} \, \textit{FlowsTo} \, \\ - \textit{FlowsTo} \, \rightarrow \, \overline{\textit{alloc}} \, (\overline{\textit{assign}} \mid \overline{\textit{store}_f} \, \textit{Alias} \, \overline{\textit{load}_f})^* \, \\ - \forall \, f \, \in \, Fields diff --git a/docs/graphs/data/lusearch.rst b/docs/graphs/data/lusearch.rst index f25992fc..fd2b1686 100644 --- a/docs/graphs/data/lusearch.rst +++ b/docs/graphs/data/lusearch.rst @@ -55,15 +55,3 @@ Edges Statistics - 2515 * - :math:`\textit{store}_f` - 580 - -Canonical grammars ------------------- - -Grammars for the field-sensitive analysis of Java programs introduced in `"Giga-scale exhaustive points-to analysis for Java in under a minute" `_. -Template for these grammars is described on the :ref:`java_points-to` page. - -.. math:: - \textit{PointsTo} \, \rightarrow \, (\textit{assign} \mid \textit{load}_f \, \textit{Alias} \, \textit{store}_f)^{*} \, \textit{alloc} \, \\ - \textit{Alias} \, \rightarrow \, \textit{PointsTo} \, \textit{FlowsTo} \, \\ - \textit{FlowsTo} \, \rightarrow \, \overline{\textit{alloc}} \, (\overline{\textit{assign}} \mid \overline{\textit{store}_f} \, \textit{Alias} \, \overline{\textit{load}_f})^* \, \\ - \forall \, f \, \in \, Fields diff --git a/docs/graphs/data/mm.rst b/docs/graphs/data/mm.rst index 3d8c6dae..840114bf 100644 --- a/docs/graphs/data/mm.rst +++ b/docs/graphs/data/mm.rst @@ -45,52 +45,3 @@ Edges Statistics - 1692161 * - a - 498918 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/mockito.rst b/docs/graphs/data/mockito.rst index 11d71b2d..c6e8363e 100644 --- a/docs/graphs/data/mockito.rst +++ b/docs/graphs/data/mockito.rst @@ -59,5 +59,3 @@ Edges Statistics - 1629 * - :math:`\overline{\textit{store}_i}` - 1629 - -.. include:: grammar_java_points_to.inc diff --git a/docs/graphs/data/nab.rst b/docs/graphs/data/nab.rst index 67a98a55..2fb82595 100644 --- a/docs/graphs/data/nab.rst +++ b/docs/graphs/data/nab.rst @@ -48,5 +48,3 @@ Edges Statistics - 1266 * - :math:`ret_i` - 678 - -.. include:: grammar_cpu17_context_sensitive_data_flow.inc diff --git a/docs/graphs/data/nab_field_sensitive_alias.rst b/docs/graphs/data/nab_field_sensitive_alias.rst index 07bef9cc..11a23a19 100644 --- a/docs/graphs/data/nab_field_sensitive_alias.rst +++ b/docs/graphs/data/nab_field_sensitive_alias.rst @@ -53,5 +53,3 @@ Edges Statistics - 1192 * - :math:`fbar_i` - 1192 - -.. include:: grammar_cpu17_field_sensitive_alias.inc diff --git a/docs/graphs/data/name_resolution_jiaozi.rst b/docs/graphs/data/name_resolution_jiaozi.rst index c3f80ef4..521d7f2d 100644 --- a/docs/graphs/data/name_resolution_jiaozi.rst +++ b/docs/graphs/data/name_resolution_jiaozi.rst @@ -53,5 +53,3 @@ Edges Statistics - 1094 * - vpsh_i - 9660 - -.. include:: grammar_name_resolution.inc diff --git a/docs/graphs/data/name_resolution_jsonpath.rst b/docs/graphs/data/name_resolution_jsonpath.rst index 67f73a8b..3b7e80da 100644 --- a/docs/graphs/data/name_resolution_jsonpath.rst +++ b/docs/graphs/data/name_resolution_jsonpath.rst @@ -53,5 +53,3 @@ Edges Statistics - 4190 * - vpsh_i - 33312 - -.. include:: grammar_name_resolution.inc diff --git a/docs/graphs/data/name_resolution_libgdx.rst b/docs/graphs/data/name_resolution_libgdx.rst index 70480f8c..8b8cbd60 100644 --- a/docs/graphs/data/name_resolution_libgdx.rst +++ b/docs/graphs/data/name_resolution_libgdx.rst @@ -53,5 +53,3 @@ Edges Statistics - 53796 * - vpsh_i - 551892 - -.. include:: grammar_name_resolution.inc diff --git a/docs/graphs/data/name_resolution_shattered_pixel_dungeon.rst b/docs/graphs/data/name_resolution_shattered_pixel_dungeon.rst index 47d5646d..59fc8c4c 100644 --- a/docs/graphs/data/name_resolution_shattered_pixel_dungeon.rst +++ b/docs/graphs/data/name_resolution_shattered_pixel_dungeon.rst @@ -53,5 +53,3 @@ Edges Statistics - 16938 * - vpsh_i - 241777 - -.. include:: grammar_name_resolution.inc diff --git a/docs/graphs/data/net.rst b/docs/graphs/data/net.rst index e63af1f4..1c677f47 100644 --- a/docs/graphs/data/net.rst +++ b/docs/graphs/data/net.rst @@ -45,52 +45,3 @@ Edges Statistics - 2692979 * - a - 807162 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/omnetpp.rst b/docs/graphs/data/omnetpp.rst index 387b0730..3a24e300 100644 --- a/docs/graphs/data/omnetpp.rst +++ b/docs/graphs/data/omnetpp.rst @@ -47,5 +47,3 @@ Edges Statistics - 240834 * - :math:`ret_i` - 177681 - -.. include:: grammar_cpu17_context_sensitive_data_flow.inc diff --git a/docs/graphs/data/omnetpp_field_sensitive_alias.rst b/docs/graphs/data/omnetpp_field_sensitive_alias.rst index d6b2055a..0a9cf2e6 100644 --- a/docs/graphs/data/omnetpp_field_sensitive_alias.rst +++ b/docs/graphs/data/omnetpp_field_sensitive_alias.rst @@ -53,5 +53,3 @@ Edges Statistics - 16822 * - :math:`fbar_i` - 16822 - -.. include:: grammar_cpu17_field_sensitive_alias.inc diff --git a/docs/graphs/data/parest.rst b/docs/graphs/data/parest.rst index 86412465..e7936bc2 100644 --- a/docs/graphs/data/parest.rst +++ b/docs/graphs/data/parest.rst @@ -47,5 +47,3 @@ Edges Statistics - 4301 * - :math:`ret_i` - 2291 - -.. include:: grammar_cpu17_context_sensitive_data_flow.inc diff --git a/docs/graphs/data/parest_field_sensitive_alias.rst b/docs/graphs/data/parest_field_sensitive_alias.rst index 4559f8c3..bc47d583 100644 --- a/docs/graphs/data/parest_field_sensitive_alias.rst +++ b/docs/graphs/data/parest_field_sensitive_alias.rst @@ -53,5 +53,3 @@ Edges Statistics - 8983 * - :math:`fbar_i` - 8983 - -.. include:: grammar_cpu17_field_sensitive_alias.inc diff --git a/docs/graphs/data/pathways.rst b/docs/graphs/data/pathways.rst index 412a25af..848c0cba 100644 --- a/docs/graphs/data/pathways.rst +++ b/docs/graphs/data/pathways.rst @@ -53,46 +53,3 @@ Edges Statistics - 3010 * - imports - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/people.rst b/docs/graphs/data/people.rst index 50fc4a4a..56f2a32b 100644 --- a/docs/graphs/data/people.rst +++ b/docs/graphs/data/people.rst @@ -93,46 +93,3 @@ Edges Statistics - 1 * - is_pet_of - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/perlbench.rst b/docs/graphs/data/perlbench.rst index 39ef7b63..837d6025 100644 --- a/docs/graphs/data/perlbench.rst +++ b/docs/graphs/data/perlbench.rst @@ -47,5 +47,3 @@ Edges Statistics - 149363 * - :math:`ret_i` - 62417 - -.. include:: grammar_cpu17_context_sensitive_data_flow.inc diff --git a/docs/graphs/data/perlbench_field_sensitive_alias.rst b/docs/graphs/data/perlbench_field_sensitive_alias.rst index c7ce1d0d..9a4352e2 100644 --- a/docs/graphs/data/perlbench_field_sensitive_alias.rst +++ b/docs/graphs/data/perlbench_field_sensitive_alias.rst @@ -53,5 +53,3 @@ Edges Statistics - 16381 * - :math:`fbar_i` - 16381 - -.. include:: grammar_cpu17_field_sensitive_alias.inc diff --git a/docs/graphs/data/pizza.rst b/docs/graphs/data/pizza.rst index 760e43f9..8a612a5e 100644 --- a/docs/graphs/data/pizza.rst +++ b/docs/graphs/data/pizza.rst @@ -87,46 +87,3 @@ Edges Statistics - 1 * - oneOf - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/pmd.rst b/docs/graphs/data/pmd.rst index 32887110..c9d0f7c4 100644 --- a/docs/graphs/data/pmd.rst +++ b/docs/graphs/data/pmd.rst @@ -55,15 +55,3 @@ Edges Statistics - 11109 * - :math:`\textit{store}_f` - 1992 - -Canonical grammars ------------------- - -Grammars for the field-sensitive analysis of Java programs introduced in `"Giga-scale exhaustive points-to analysis for Java in under a minute" `_. -Template for these grammars is described on the :ref:`java_points-to` page. - -.. math:: - \textit{PointsTo} \, \rightarrow \, (\textit{assign} \mid \textit{load}_f \, \textit{Alias} \, \textit{store}_f)^{*} \, \textit{alloc} \, \\ - \textit{Alias} \, \rightarrow \, \textit{PointsTo} \, \textit{FlowsTo} \, \\ - \textit{FlowsTo} \, \rightarrow \, \overline{\textit{alloc}} \, (\overline{\textit{assign}} \mid \overline{\textit{store}_f} \, \textit{Alias} \, \overline{\textit{load}_f})^* \, \\ - \forall \, f \, \in \, Fields diff --git a/docs/graphs/data/postgre.rst b/docs/graphs/data/postgre.rst index d033290c..27575e4e 100644 --- a/docs/graphs/data/postgre.rst +++ b/docs/graphs/data/postgre.rst @@ -45,52 +45,3 @@ Edges Statistics - 3468946 * - a - 1209597 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/povray.rst b/docs/graphs/data/povray.rst index f7a2c86f..f1ffb318 100644 --- a/docs/graphs/data/povray.rst +++ b/docs/graphs/data/povray.rst @@ -47,5 +47,3 @@ Edges Statistics - 108577 * - :math:`ret_i` - 56231 - -.. include:: grammar_cpu17_context_sensitive_data_flow.inc diff --git a/docs/graphs/data/povray_field_sensitive_alias.rst b/docs/graphs/data/povray_field_sensitive_alias.rst index 4df88e21..cc23f014 100644 --- a/docs/graphs/data/povray_field_sensitive_alias.rst +++ b/docs/graphs/data/povray_field_sensitive_alias.rst @@ -53,5 +53,3 @@ Edges Statistics - 6951 * - :math:`fbar_i` - 6951 - -.. include:: grammar_cpu17_field_sensitive_alias.inc diff --git a/docs/graphs/data/pr.rst b/docs/graphs/data/pr.rst index bd271af8..77138592 100644 --- a/docs/graphs/data/pr.rst +++ b/docs/graphs/data/pr.rst @@ -47,52 +47,3 @@ Edges Statistics - 359 * - a - 333 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/provenance_airflow.rst b/docs/graphs/data/provenance_airflow.rst index 37c3efbf..b0a328cb 100644 --- a/docs/graphs/data/provenance_airflow.rst +++ b/docs/graphs/data/provenance_airflow.rst @@ -71,5 +71,3 @@ Edges Statistics - 42997 * - wasAttributedTo_r - 42997 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_celery.rst b/docs/graphs/data/provenance_celery.rst index 0bb7f083..f4687435 100644 --- a/docs/graphs/data/provenance_celery.rst +++ b/docs/graphs/data/provenance_celery.rst @@ -71,5 +71,3 @@ Edges Statistics - 2897 * - wasAttributedTo_r - 2897 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_click.rst b/docs/graphs/data/provenance_click.rst index 3453adc2..91385831 100644 --- a/docs/graphs/data/provenance_click.rst +++ b/docs/graphs/data/provenance_click.rst @@ -71,5 +71,3 @@ Edges Statistics - 402 * - wasAttributedTo_r - 402 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_django.rst b/docs/graphs/data/provenance_django.rst index 575d89cf..0ef3eba2 100644 --- a/docs/graphs/data/provenance_django.rst +++ b/docs/graphs/data/provenance_django.rst @@ -71,5 +71,3 @@ Edges Statistics - 11427 * - wasAttributedTo_r - 11427 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_fastapi.rst b/docs/graphs/data/provenance_fastapi.rst index 16c252d1..08f0b3b1 100644 --- a/docs/graphs/data/provenance_fastapi.rst +++ b/docs/graphs/data/provenance_fastapi.rst @@ -71,5 +71,3 @@ Edges Statistics - 3177 * - wasAttributedTo_r - 3177 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_flask.rst b/docs/graphs/data/provenance_flask.rst index ef5b7042..2c20f9c5 100644 --- a/docs/graphs/data/provenance_flask.rst +++ b/docs/graphs/data/provenance_flask.rst @@ -71,5 +71,3 @@ Edges Statistics - 694 * - wasAttributedTo_r - 694 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_httpx.rst b/docs/graphs/data/provenance_httpx.rst index 46d8ae53..5623d575 100644 --- a/docs/graphs/data/provenance_httpx.rst +++ b/docs/graphs/data/provenance_httpx.rst @@ -71,5 +71,3 @@ Edges Statistics - 362 * - wasAttributedTo_r - 362 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_itsdangerous.rst b/docs/graphs/data/provenance_itsdangerous.rst index 68ad07ca..76007657 100644 --- a/docs/graphs/data/provenance_itsdangerous.rst +++ b/docs/graphs/data/provenance_itsdangerous.rst @@ -71,5 +71,3 @@ Edges Statistics - 206 * - wasAttributedTo_r - 206 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_jinja.rst b/docs/graphs/data/provenance_jinja.rst index 6e0d707a..2448b904 100644 --- a/docs/graphs/data/provenance_jinja.rst +++ b/docs/graphs/data/provenance_jinja.rst @@ -71,5 +71,3 @@ Edges Statistics - 527 * - wasAttributedTo_r - 527 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_pandas.rst b/docs/graphs/data/provenance_pandas.rst index de8236a8..1201c375 100644 --- a/docs/graphs/data/provenance_pandas.rst +++ b/docs/graphs/data/provenance_pandas.rst @@ -71,5 +71,3 @@ Edges Statistics - 6416 * - wasAttributedTo_r - 6416 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_pluggy.rst b/docs/graphs/data/provenance_pluggy.rst index cbf5a8cf..474a695e 100644 --- a/docs/graphs/data/provenance_pluggy.rst +++ b/docs/graphs/data/provenance_pluggy.rst @@ -71,5 +71,3 @@ Edges Statistics - 154 * - wasAttributedTo_r - 154 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_requests.rst b/docs/graphs/data/provenance_requests.rst index 5be78e54..b3a9119e 100644 --- a/docs/graphs/data/provenance_requests.rst +++ b/docs/graphs/data/provenance_requests.rst @@ -71,5 +71,3 @@ Edges Statistics - 300 * - wasAttributedTo_r - 300 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_sampleproject.rst b/docs/graphs/data/provenance_sampleproject.rst index 49ab9c35..7d129db9 100644 --- a/docs/graphs/data/provenance_sampleproject.rst +++ b/docs/graphs/data/provenance_sampleproject.rst @@ -71,5 +71,3 @@ Edges Statistics - 64 * - wasAttributedTo_r - 64 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_scikit_learn.rst b/docs/graphs/data/provenance_scikit_learn.rst index 29fc746a..438ec24b 100644 --- a/docs/graphs/data/provenance_scikit_learn.rst +++ b/docs/graphs/data/provenance_scikit_learn.rst @@ -71,5 +71,3 @@ Edges Statistics - 5368 * - wasAttributedTo_r - 5368 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_sphinx.rst b/docs/graphs/data/provenance_sphinx.rst index d3294f81..044e3e87 100644 --- a/docs/graphs/data/provenance_sphinx.rst +++ b/docs/graphs/data/provenance_sphinx.rst @@ -71,5 +71,3 @@ Edges Statistics - 6515 * - wasAttributedTo_r - 6515 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_superset.rst b/docs/graphs/data/provenance_superset.rst index 39eabac4..902a081b 100644 --- a/docs/graphs/data/provenance_superset.rst +++ b/docs/graphs/data/provenance_superset.rst @@ -71,5 +71,3 @@ Edges Statistics - 37077 * - wasAttributedTo_r - 37077 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_wikipedia_provenance.rst b/docs/graphs/data/provenance_wikipedia_provenance.rst index 076b5a2d..95baaca7 100644 --- a/docs/graphs/data/provenance_wikipedia_provenance.rst +++ b/docs/graphs/data/provenance_wikipedia_provenance.rst @@ -71,5 +71,3 @@ Edges Statistics - 125 * - wasAttributedTo_r - 125 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/provenance_zulip.rst b/docs/graphs/data/provenance_zulip.rst index 91cd90e3..131c37f3 100644 --- a/docs/graphs/data/provenance_zulip.rst +++ b/docs/graphs/data/provenance_zulip.rst @@ -71,5 +71,3 @@ Edges Statistics - 29409 * - wasAttributedTo_r - 29409 - -.. include:: grammar_data_provenance.inc diff --git a/docs/graphs/data/security.rst b/docs/graphs/data/security.rst index fbb94c50..7bbc054c 100644 --- a/docs/graphs/data/security.rst +++ b/docs/graphs/data/security.rst @@ -45,52 +45,3 @@ Edges Statistics - 2319987 * - a - 683339 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/skos.rst b/docs/graphs/data/skos.rst index 9d2ed29a..d8c8626d 100644 --- a/docs/graphs/data/skos.rst +++ b/docs/graphs/data/skos.rst @@ -85,46 +85,3 @@ Edges Statistics - 1 * - subClassOf - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/sound.rst b/docs/graphs/data/sound.rst index b9258a53..407ef1b2 100644 --- a/docs/graphs/data/sound.rst +++ b/docs/graphs/data/sound.rst @@ -45,52 +45,3 @@ Edges Statistics - 2352573 * - a - 697159 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/sunflow.rst b/docs/graphs/data/sunflow.rst index 621b8780..b675600c 100644 --- a/docs/graphs/data/sunflow.rst +++ b/docs/graphs/data/sunflow.rst @@ -55,15 +55,3 @@ Edges Statistics - 2305 * - :math:`\textit{store}_f` - 374 - -Canonical grammars ------------------- - -Grammars for the field-sensitive analysis of Java programs introduced in `"Giga-scale exhaustive points-to analysis for Java in under a minute" `_. -Template for these grammars is described on the :ref:`java_points-to` page. - -.. math:: - \textit{PointsTo} \, \rightarrow \, (\textit{assign} \mid \textit{load}_f \, \textit{Alias} \, \textit{store}_f)^{*} \, \textit{alloc} \, \\ - \textit{Alias} \, \rightarrow \, \textit{PointsTo} \, \textit{FlowsTo} \, \\ - \textit{FlowsTo} \, \rightarrow \, \overline{\textit{alloc}} \, (\overline{\textit{assign}} \mid \overline{\textit{store}_f} \, \textit{Alias} \, \overline{\textit{load}_f})^* \, \\ - \forall \, f \, \in \, Fields diff --git a/docs/graphs/data/taxonomy.rst b/docs/graphs/data/taxonomy.rst index a0a3e82b..0a22e65c 100644 --- a/docs/graphs/data/taxonomy.rst +++ b/docs/graphs/data/taxonomy.rst @@ -85,46 +85,3 @@ Edges Statistics - 6433 * - imports - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/taxonomy_hierarchy.rst b/docs/graphs/data/taxonomy_hierarchy.rst index a9239f17..dedc5711 100644 --- a/docs/graphs/data/taxonomy_hierarchy.rst +++ b/docs/graphs/data/taxonomy_hierarchy.rst @@ -45,46 +45,3 @@ Edges Statistics - Num Edge Label * - subClassOf - 32876289 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/tomcat.rst b/docs/graphs/data/tomcat.rst index 40ce4fb2..51bbe3d8 100644 --- a/docs/graphs/data/tomcat.rst +++ b/docs/graphs/data/tomcat.rst @@ -55,15 +55,3 @@ Edges Statistics - 15198 * - :math:`\textit{store}_f` - 3251 - -Canonical grammars ------------------- - -Grammars for the field-sensitive analysis of Java programs introduced in `"Giga-scale exhaustive points-to analysis for Java in under a minute" `_. -Template for these grammars is described on the :ref:`java_points-to` page. - -.. math:: - \textit{PointsTo} \, \rightarrow \, (\textit{assign} \mid \textit{load}_f \, \textit{Alias} \, \textit{store}_f)^{*} \, \textit{alloc} \, \\ - \textit{Alias} \, \rightarrow \, \textit{PointsTo} \, \textit{FlowsTo} \, \\ - \textit{FlowsTo} \, \rightarrow \, \overline{\textit{alloc}} \, (\overline{\textit{assign}} \mid \overline{\textit{store}_f} \, \textit{Alias} \, \overline{\textit{load}_f})^* \, \\ - \forall \, f \, \in \, Fields diff --git a/docs/graphs/data/tradebeans.rst b/docs/graphs/data/tradebeans.rst index c371bb74..7fdcc7cd 100644 --- a/docs/graphs/data/tradebeans.rst +++ b/docs/graphs/data/tradebeans.rst @@ -55,15 +55,3 @@ Edges Statistics - 49794 * - :math:`\textit{store}_f` - 12383 - -Canonical grammars ------------------- - -Grammars for the field-sensitive analysis of Java programs introduced in `"Giga-scale exhaustive points-to analysis for Java in under a minute" `_. -Template for these grammars is described on the :ref:`java_points-to` page. - -.. math:: - \textit{PointsTo} \, \rightarrow \, (\textit{assign} \mid \textit{load}_f \, \textit{Alias} \, \textit{store}_f)^{*} \, \textit{alloc} \, \\ - \textit{Alias} \, \rightarrow \, \textit{PointsTo} \, \textit{FlowsTo} \, \\ - \textit{FlowsTo} \, \rightarrow \, \overline{\textit{alloc}} \, (\overline{\textit{assign}} \mid \overline{\textit{store}_f} \, \textit{Alias} \, \overline{\textit{load}_f})^* \, \\ - \forall \, f \, \in \, Fields diff --git a/docs/graphs/data/tradesoap.rst b/docs/graphs/data/tradesoap.rst index fdac8644..3cacb0c2 100644 --- a/docs/graphs/data/tradesoap.rst +++ b/docs/graphs/data/tradesoap.rst @@ -55,15 +55,3 @@ Edges Statistics - 49858 * - :math:`\textit{store}_f` - 12408 - -Canonical grammars ------------------- - -Grammars for the field-sensitive analysis of Java programs introduced in `"Giga-scale exhaustive points-to analysis for Java in under a minute" `_. -Template for these grammars is described on the :ref:`java_points-to` page. - -.. math:: - \textit{PointsTo} \, \rightarrow \, (\textit{assign} \mid \textit{load}_f \, \textit{Alias} \, \textit{store}_f)^{*} \, \textit{alloc} \, \\ - \textit{Alias} \, \rightarrow \, \textit{PointsTo} \, \textit{FlowsTo} \, \\ - \textit{FlowsTo} \, \rightarrow \, \overline{\textit{alloc}} \, (\overline{\textit{assign}} \mid \overline{\textit{store}_f} \, \textit{Alias} \, \overline{\textit{load}_f})^* \, \\ - \forall \, f \, \in \, Fields diff --git a/docs/graphs/data/travel.rst b/docs/graphs/data/travel.rst index 4cf93b98..074fe84c 100644 --- a/docs/graphs/data/travel.rst +++ b/docs/graphs/data/travel.rst @@ -85,46 +85,3 @@ Edges Statistics - 1 * - versionInfo - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/unigraph_1.rst b/docs/graphs/data/unigraph_1.rst index 097f7812..3c0222f2 100644 --- a/docs/graphs/data/unigraph_1.rst +++ b/docs/graphs/data/unigraph_1.rst @@ -67,19 +67,3 @@ Edges Statistics - 1621 * - refers_to_r - 1621 - -Grammar ------------------- - -The grammar file is attached to the archive. - -.. math:: - - S &\to Seq \quad IsAssociated \quad IsSimilar \\ - Seq &\to IsSimilar \quad (codes\_for \quad IsSimilar)? \\ - IsSimilar &\to \varepsilon \\ - &\mid has \quad IsSimilar \quad has_{r} \\ - &\mid is\_homologous\_to \quad IsSimilar \quad is\_homologous\_to_{r} \quad IsSimilar \\ - &\mid belongs\_to \quad IsSimilar \quad belongs\_to_{r} \\ - &\mid participate\_in \quad IsSimilar \quad participate\_in_{r} \\ - IsAssociated &\to refers\_to \quad refers\_to_{r} diff --git a/docs/graphs/data/unigraph_10.rst b/docs/graphs/data/unigraph_10.rst index b8a913d6..7400a8f3 100644 --- a/docs/graphs/data/unigraph_10.rst +++ b/docs/graphs/data/unigraph_10.rst @@ -67,19 +67,3 @@ Edges Statistics - 1144599 * - refers_to_r - 1144599 - -Grammar ------------------- - -The grammar file is attached to the archive. - -.. math:: - - S &\to Seq \quad IsAssociated \quad IsSimilar \\ - Seq &\to IsSimilar \quad (codes\_for \quad IsSimilar)? \\ - IsSimilar &\to \varepsilon \\ - &\mid has \quad IsSimilar \quad has_{r} \\ - &\mid is\_homologous\_to \quad IsSimilar \quad is\_homologous\_to_{r} \quad IsSimilar \\ - &\mid belongs\_to \quad IsSimilar \quad belongs\_to_{r} \\ - &\mid participate\_in \quad IsSimilar \quad participate\_in_{r} \\ - IsAssociated &\to refers\_to \quad refers\_to_{r} diff --git a/docs/graphs/data/unigraph_2.rst b/docs/graphs/data/unigraph_2.rst index 2bf2ae31..6fcbf097 100644 --- a/docs/graphs/data/unigraph_2.rst +++ b/docs/graphs/data/unigraph_2.rst @@ -67,19 +67,3 @@ Edges Statistics - 13875 * - refers_to_r - 13875 - -Grammar ------------------- - -The grammar file is attached to the archive. - -.. math:: - - S &\to Seq \quad IsAssociated \quad IsSimilar \\ - Seq &\to IsSimilar \quad (codes\_for \quad IsSimilar)? \\ - IsSimilar &\to \varepsilon \\ - &\mid has \quad IsSimilar \quad has_{r} \\ - &\mid is\_homologous\_to \quad IsSimilar \quad is\_homologous\_to_{r} \quad IsSimilar \\ - &\mid belongs\_to \quad IsSimilar \quad belongs\_to_{r} \\ - &\mid participate\_in \quad IsSimilar \quad participate\_in_{r} \\ - IsAssociated &\to refers\_to \quad refers\_to_{r} diff --git a/docs/graphs/data/unigraph_3.rst b/docs/graphs/data/unigraph_3.rst index a7ee45d0..48d2a2dc 100644 --- a/docs/graphs/data/unigraph_3.rst +++ b/docs/graphs/data/unigraph_3.rst @@ -67,19 +67,3 @@ Edges Statistics - 14625 * - refers_to_r - 14625 - -Grammar ------------------- - -The grammar file is attached to the archive. - -.. math:: - - S &\to Seq \quad IsAssociated \quad IsSimilar \\ - Seq &\to IsSimilar \quad (codes\_for \quad IsSimilar)? \\ - IsSimilar &\to \varepsilon \\ - &\mid has \quad IsSimilar \quad has_{r} \\ - &\mid is\_homologous\_to \quad IsSimilar \quad is\_homologous\_to_{r} \quad IsSimilar \\ - &\mid belongs\_to \quad IsSimilar \quad belongs\_to_{r} \\ - &\mid participate\_in \quad IsSimilar \quad participate\_in_{r} \\ - IsAssociated &\to refers\_to \quad refers\_to_{r} diff --git a/docs/graphs/data/unigraph_4.rst b/docs/graphs/data/unigraph_4.rst index febe90fb..7b1aff39 100644 --- a/docs/graphs/data/unigraph_4.rst +++ b/docs/graphs/data/unigraph_4.rst @@ -67,19 +67,3 @@ Edges Statistics - 228018 * - refers_to_r - 228018 - -Grammar ------------------- - -The grammar file is attached to the archive. - -.. math:: - - S &\to Seq \quad IsAssociated \quad IsSimilar \\ - Seq &\to IsSimilar \quad (codes\_for \quad IsSimilar)? \\ - IsSimilar &\to \varepsilon \\ - &\mid has \quad IsSimilar \quad has_{r} \\ - &\mid is\_homologous\_to \quad IsSimilar \quad is\_homologous\_to_{r} \quad IsSimilar \\ - &\mid belongs\_to \quad IsSimilar \quad belongs\_to_{r} \\ - &\mid participate\_in \quad IsSimilar \quad participate\_in_{r} \\ - IsAssociated &\to refers\_to \quad refers\_to_{r} diff --git a/docs/graphs/data/unigraph_5.rst b/docs/graphs/data/unigraph_5.rst index 8cd2ef2d..02f19e74 100644 --- a/docs/graphs/data/unigraph_5.rst +++ b/docs/graphs/data/unigraph_5.rst @@ -67,19 +67,3 @@ Edges Statistics - 157586 * - refers_to_r - 157586 - -Grammar ------------------- - -The grammar file is attached to the archive. - -.. math:: - - S &\to Seq \quad IsAssociated \quad IsSimilar \\ - Seq &\to IsSimilar \quad (codes\_for \quad IsSimilar)? \\ - IsSimilar &\to \varepsilon \\ - &\mid has \quad IsSimilar \quad has_{r} \\ - &\mid is\_homologous\_to \quad IsSimilar \quad is\_homologous\_to_{r} \quad IsSimilar \\ - &\mid belongs\_to \quad IsSimilar \quad belongs\_to_{r} \\ - &\mid participate\_in \quad IsSimilar \quad participate\_in_{r} \\ - IsAssociated &\to refers\_to \quad refers\_to_{r} diff --git a/docs/graphs/data/unigraph_6.rst b/docs/graphs/data/unigraph_6.rst index 8c83d3f4..bee865e7 100644 --- a/docs/graphs/data/unigraph_6.rst +++ b/docs/graphs/data/unigraph_6.rst @@ -67,19 +67,3 @@ Edges Statistics - 271304 * - refers_to_r - 271304 - -Grammar ------------------- - -The grammar file is attached to the archive. - -.. math:: - - S &\to Seq \quad IsAssociated \quad IsSimilar \\ - Seq &\to IsSimilar \quad (codes\_for \quad IsSimilar)? \\ - IsSimilar &\to \varepsilon \\ - &\mid has \quad IsSimilar \quad has_{r} \\ - &\mid is\_homologous\_to \quad IsSimilar \quad is\_homologous\_to_{r} \quad IsSimilar \\ - &\mid belongs\_to \quad IsSimilar \quad belongs\_to_{r} \\ - &\mid participate\_in \quad IsSimilar \quad participate\_in_{r} \\ - IsAssociated &\to refers\_to \quad refers\_to_{r} diff --git a/docs/graphs/data/unigraph_7.rst b/docs/graphs/data/unigraph_7.rst index ed3270ca..0abfaa19 100644 --- a/docs/graphs/data/unigraph_7.rst +++ b/docs/graphs/data/unigraph_7.rst @@ -67,19 +67,3 @@ Edges Statistics - 259105 * - refers_to_r - 259105 - -Grammar ------------------- - -The grammar file is attached to the archive. - -.. math:: - - S &\to Seq \quad IsAssociated \quad IsSimilar \\ - Seq &\to IsSimilar \quad (codes\_for \quad IsSimilar)? \\ - IsSimilar &\to \varepsilon \\ - &\mid has \quad IsSimilar \quad has_{r} \\ - &\mid is\_homologous\_to \quad IsSimilar \quad is\_homologous\_to_{r} \quad IsSimilar \\ - &\mid belongs\_to \quad IsSimilar \quad belongs\_to_{r} \\ - &\mid participate\_in \quad IsSimilar \quad participate\_in_{r} \\ - IsAssociated &\to refers\_to \quad refers\_to_{r} diff --git a/docs/graphs/data/unigraph_8.rst b/docs/graphs/data/unigraph_8.rst index be565419..cd4c6a4b 100644 --- a/docs/graphs/data/unigraph_8.rst +++ b/docs/graphs/data/unigraph_8.rst @@ -67,19 +67,3 @@ Edges Statistics - 406821 * - refers_to_r - 406821 - -Grammar ------------------- - -The grammar file is attached to the archive. - -.. math:: - - S &\to Seq \quad IsAssociated \quad IsSimilar \\ - Seq &\to IsSimilar \quad (codes\_for \quad IsSimilar)? \\ - IsSimilar &\to \varepsilon \\ - &\mid has \quad IsSimilar \quad has_{r} \\ - &\mid is\_homologous\_to \quad IsSimilar \quad is\_homologous\_to_{r} \quad IsSimilar \\ - &\mid belongs\_to \quad IsSimilar \quad belongs\_to_{r} \\ - &\mid participate\_in \quad IsSimilar \quad participate\_in_{r} \\ - IsAssociated &\to refers\_to \quad refers\_to_{r} diff --git a/docs/graphs/data/unigraph_9.rst b/docs/graphs/data/unigraph_9.rst index 77ccf165..d5571997 100644 --- a/docs/graphs/data/unigraph_9.rst +++ b/docs/graphs/data/unigraph_9.rst @@ -67,19 +67,3 @@ Edges Statistics - 421446 * - refers_to_r - 421446 - -Grammar ------------------- - -The grammar file is attached to the archive. - -.. math:: - - S &\to Seq \quad IsAssociated \quad IsSimilar \\ - Seq &\to IsSimilar \quad (codes\_for \quad IsSimilar)? \\ - IsSimilar &\to \varepsilon \\ - &\mid has \quad IsSimilar \quad has_{r} \\ - &\mid is\_homologous\_to \quad IsSimilar \quad is\_homologous\_to_{r} \quad IsSimilar \\ - &\mid belongs\_to \quad IsSimilar \quad belongs\_to_{r} \\ - &\mid participate\_in \quad IsSimilar \quad participate\_in_{r} \\ - IsAssociated &\to refers\_to \quad refers\_to_{r} diff --git a/docs/graphs/data/univ.rst b/docs/graphs/data/univ.rst index 7741e962..1f2e27ff 100644 --- a/docs/graphs/data/univ.rst +++ b/docs/graphs/data/univ.rst @@ -71,46 +71,3 @@ Edges Statistics - 1 * - comment - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/wc.rst b/docs/graphs/data/wc.rst index a4cd9683..424bf135 100644 --- a/docs/graphs/data/wc.rst +++ b/docs/graphs/data/wc.rst @@ -47,52 +47,3 @@ Edges Statistics - 156 * - a - 113 - - -Canonical grammars ------------------- - -.. note:: - - In order to get the original graph you must apply function :obj:`change_edges ` with ``mapping={"a": "A", "d": "D"}`` to this graph. In this case these grammars must be updated. - -Grammars for the alias analysis of C programs introduced in `"Demand-driven alias analysis for C" `_. -Template for these grammars is described on the :ref:`c_alias` page. - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, V_1 \, V_2 \, V_3 \, \\ - V_1 \, \rightarrow \, \varepsilon \, \\ - V_1 \, \rightarrow \, V_2 \, \overline{a} \, V_1 \, \\ - V_2 \, \rightarrow \, \varepsilon \, \\ - V_2 \, \rightarrow \, S \, \\ - V_3 \, \rightarrow \, \varepsilon \, \\ - V_3 \, \rightarrow \, a \, V_2 \, V_3 \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> d_r V d - V -> V1 V2 V3 - V1 -> epsilon - V1 -> V2 a_r V1 - V2 -> epsilon - V2 -> S - V3 -> epsilon - V3 -> a V2 V3 - ----- - -.. math:: - - S \, \rightarrow \, \overline{d} \, V \, d \, \\ - V \, \rightarrow \, ((S \mid \varepsilon) \, \overline{a})^{*} \, (S \mid \varepsilon) \, (a \, (S \mid \varepsilon))^{*} \, \\ - -`Pyformlang RSA `_: - -.. code-block:: python - - S -> d_r V d - V -> ((S|epsilon) a_r)* (S|epsilon) (a (S|epsilon))* diff --git a/docs/graphs/data/wine.rst b/docs/graphs/data/wine.rst index 30155a23..d8b1eaea 100644 --- a/docs/graphs/data/wine.rst +++ b/docs/graphs/data/wine.rst @@ -113,46 +113,3 @@ Edges Statistics - 1 * - hasVintageYear - 1 - - -Canonical grammars ------------------- - -Nested parentheses grammars introduced in `"Context-Free Path Queries on RDF Graphs" `_. -Template for these grammars is described on the :ref:`nested_parentheses` page. - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - S -> type_r S type | type_r type - ----- - -.. math:: - - S \, \rightarrow \, \overline{subClassOf} \, S \, subClassOf \, \mid \, \overline{subClassOf} \, subClassOf \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> subClassOf_r S subClassOf | subClassOf_r subClassOf - ----- - -.. math:: - - S \, \rightarrow \, \overline{type} \, S \, type \, \mid \, \overline{type} \, type \, \\ - -`Pyformlang CFG `_: - -.. code-block:: python - - S -> type_r S type | type_r type diff --git a/docs/graphs/data/x264.rst b/docs/graphs/data/x264.rst index 7b261cca..385ad684 100644 --- a/docs/graphs/data/x264.rst +++ b/docs/graphs/data/x264.rst @@ -47,5 +47,3 @@ Edges Statistics - 6050 * - :math:`ret_i` - 3637 - -.. include:: grammar_cpu17_context_sensitive_data_flow.inc diff --git a/docs/graphs/data/x264_field_sensitive_alias.rst b/docs/graphs/data/x264_field_sensitive_alias.rst index f821166c..111985d7 100644 --- a/docs/graphs/data/x264_field_sensitive_alias.rst +++ b/docs/graphs/data/x264_field_sensitive_alias.rst @@ -53,5 +53,3 @@ Edges Statistics - 9532 * - :math:`fbar_i` - 9532 - -.. include:: grammar_cpu17_field_sensitive_alias.inc diff --git a/docs/graphs/data/xalan.rst b/docs/graphs/data/xalan.rst index 3b241caa..a8d65c52 100644 --- a/docs/graphs/data/xalan.rst +++ b/docs/graphs/data/xalan.rst @@ -55,15 +55,3 @@ Edges Statistics - 11813 * - :math:`\textit{store}_f` - 2083 - -Canonical grammars ------------------- - -Grammars for the field-sensitive analysis of Java programs introduced in `"Giga-scale exhaustive points-to analysis for Java in under a minute" `_. -Template for these grammars is described on the :ref:`java_points-to` page. - -.. math:: - \textit{PointsTo} \, \rightarrow \, (\textit{assign} \mid \textit{load}_f \, \textit{Alias} \, \textit{store}_f)^{*} \, \textit{alloc} \, \\ - \textit{Alias} \, \rightarrow \, \textit{PointsTo} \, \textit{FlowsTo} \, \\ - \textit{FlowsTo} \, \rightarrow \, \overline{\textit{alloc}} \, (\overline{\textit{assign}} \mid \overline{\textit{store}_f} \, \textit{Alias} \, \overline{\textit{load}_f})^* \, \\ - \forall \, f \, \in \, Fields diff --git a/docs/graphs/data/xz.rst b/docs/graphs/data/xz.rst index e7e64dc2..3db0e9cb 100644 --- a/docs/graphs/data/xz.rst +++ b/docs/graphs/data/xz.rst @@ -48,5 +48,3 @@ Edges Statistics - 2281 * - :math:`ret_i` - 1172 - -.. include:: grammar_cpu17_context_sensitive_data_flow.inc diff --git a/docs/graphs/data/xz_field_sensitive_alias.rst b/docs/graphs/data/xz_field_sensitive_alias.rst index 624c4732..37c2126f 100644 --- a/docs/graphs/data/xz_field_sensitive_alias.rst +++ b/docs/graphs/data/xz_field_sensitive_alias.rst @@ -53,5 +53,3 @@ Edges Statistics - 1193 * - :math:`fbar_i` - 1193 - -.. include:: grammar_cpu17_field_sensitive_alias.inc From 07c9a4c7f4568877faa79910747eab5cefea5755 Mon Sep 17 00:00:00 2001 From: gsv Date: Fri, 18 Sep 2026 09:36:11 +0300 Subject: [PATCH 037/277] docs(41-S5): teach the contribution flow that grammars live on category pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Contributors adding a graph can now hit three situations, and the templates had to cover all of them: a graph for an existing category (no grammar text needed — just name which of the category's grammars apply), a new grammar for an existing category (grammar added to the category page plus a new table column), and a graph for a new category (a new category page is created carrying the canonical grammars). Both graph templates gain a Category field in the Info table so the case is explicit, and their 'Canonical grammars' section is restructured around these three cases. The add-graph skill's Documentation step mirrors the same cases, and the Graphs index states that the canonical grammar behind each table column is documented on the category page. --- .github/ISSUE_TEMPLATE/graph-add-template.md | 11 +++++++-- .github/PULL_REQUEST_TEMPLATE/new_graph.md | 11 +++++++-- .opencode/skills/add-graph/SKILL.md | 24 ++++++++++++++++---- docs/graphs/index.rst | 5 ++++ 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/graph-add-template.md b/.github/ISSUE_TEMPLATE/graph-add-template.md index cbc95800..cff99f9e 100644 --- a/.github/ISSUE_TEMPLATE/graph-add-template.md +++ b/.github/ISSUE_TEMPLATE/graph-add-template.md @@ -13,6 +13,7 @@ assignees: rustam-azimov, vadyushkins | | | |---|---| | Full Name | ```` | +| Category | ``" for a new category>`` | | Version | ```` | | Origin | [link](````) | @@ -34,6 +35,12 @@ List the stored labels only (no `_r` reversed-edge rows). A family of indexed la ## Canonical grammars - +Canonical grammars are documented on the category page, not on the per-graph page. Pick the case that applies: - +1. **Graph for an existing category** — name the grammar(s) from the category's "Canonical grammars" section that apply to this graph; they become the table column(s) filled in for the new row. No new grammar text. +2. **New grammar for an existing category** — provide the grammar below; it will be added to the category page and a new column to its table. +3. **Graph for a new category** — provide the canonical grammar(s) below; a new category page will be created with them. + + + + diff --git a/.github/PULL_REQUEST_TEMPLATE/new_graph.md b/.github/PULL_REQUEST_TEMPLATE/new_graph.md index 3c65a224..5c67c3d9 100644 --- a/.github/PULL_REQUEST_TEMPLATE/new_graph.md +++ b/.github/PULL_REQUEST_TEMPLATE/new_graph.md @@ -4,6 +4,7 @@ | | | |---|---| | Full Name | ```` | +| Category | ``" for a new category>`` | | Version | ```` | | Origin | [link](````) | @@ -25,6 +26,12 @@ List the stored labels only (no `_r` reversed-edge rows). A family of indexed la ## Canonical grammars - +Canonical grammars are documented on the category page, not on the per-graph page. Pick the case that applies: - +1. **Graph for an existing category** — name the grammar(s) from the category's "Canonical grammars" section that apply to this graph; they become the table column(s) filled in for the new row. No new grammar text. +2. **New grammar for an existing category** — provide the grammar below; it will be added to the category page and a new column to its table. +3. **Graph for a new category** — provide the canonical grammar(s) below; a new category page will be created with them. + + + + diff --git a/.opencode/skills/add-graph/SKILL.md b/.opencode/skills/add-graph/SKILL.md index a8782037..50ef99cd 100644 --- a/.opencode/skills/add-graph/SKILL.md +++ b/.opencode/skills/add-graph/SKILL.md @@ -34,14 +34,28 @@ The archive layout and the label conventions are documented once in the ## Documentation 1. Create the per-graph page `docs/graphs/data/.rst`, following the - structure of an existing page (description, statistics tables, canonical - grammars). Statistics conventions: the PR template is the source of truth. -2. Register it **twice**: a row in the per-category table of its source area + structure of an existing page (description, statistics tables). The page + carries **no** grammar section: canonical grammars are documented once on + the category page. Statistics conventions: the PR template is the source + of truth. +2. Handle the grammar case from the PR template's "Canonical grammars" + section: + - *existing category, existing grammar(s)* — nothing to add; the new table + row fills in the matching column(s); + - *new grammar for an existing category* — append the grammar to the + category page's "Canonical grammars" section and add a column to its + table; + - *new category* — create `docs/graphs/.rst` with the category + description, the graph table (one column per grammar), and the + "Canonical grammars" section. +3. Register it **twice**: a row in the per-category table of its source area (`docs/graphs/.rst`) and an entry in the matching captioned toctree of `docs/graphs/index.rst` (the left navigation bar is generated from those toctrees). Keep both in the same order, and bump the category's - graph count in the Contents table of `docs/graphs/index.rst`. -3. Fill the new row's `Size (MB)` cell with the size the upload tool + graph count in the Contents table of `docs/graphs/index.rst`. For a new + category, also add its page to the `docs/graphs/index.rst` toctree and a + row to the Contents table. + 4. Fill the new row's `Size (MB)` cell with the size the upload tool reported, then run `python utils/archive_sizes.py --update` before committing so every table row — including the new one — matches S3 (see the "Archive sizes" section of `docs/utils.rst`). diff --git a/docs/graphs/index.rst b/docs/graphs/index.rst index 07ee11f3..c6e940d4 100644 --- a/docs/graphs/index.rst +++ b/docs/graphs/index.rst @@ -77,6 +77,11 @@ not been computed yet; an empty cell means the grammar does not apply to that graph. Each table also has a ``Size (MB)`` column: the download size of the graph's archive, in megabytes. +The canonical grammar behind each column is documented once on the +respective category page, in its "Canonical grammars" section — a grammar +is canonical for the whole category, so the per-graph pages do not repeat +it. + .. list-table:: :header-rows: 1 From 76aa685a26a0daec64eb87d5312df47edcb64385 Mon Sep 17 00:00:00 2001 From: gsv Date: Fri, 18 Sep 2026 09:52:42 +0300 Subject: [PATCH 038/277] docs(41-S6): verify the docs build and record the subtask outcomes Clean rebuild (make clean html) succeeds under the no-warnings policy: zero warnings, all eight category pages render their 'Canonical grammars' section (the rdf page shows all four grammars including broaderTransitive), and none of the 113 graph pages still carries one. Record the per-subtask commit hashes and the verification result in the detailed plan. --- tasks/detailed_plan.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index 25e32833..d96075f2 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -175,3 +175,28 @@ few graph pages (section gone). - Build must exit clean under the project's no-warnings configuration. - Grep the build log for `grammar_*.inc` (no unresolved includes) and for dangling refs. + +### S7: Mark task 41 done in the task log + +**Code:** n/a. Modify `tasks/tasks.md`, `tasks/detailed_plan.md`. +**Tests:** n/a. +**Docs:** n/a (task tracking files). + +**Spec:** +- Prepend `[done]` to the Task 41 line in `tasks/tasks.md` (description + untouched). +- Record the final status of all subtasks below. + +## Status + +- S1 c725178 — task log + this plan. +- S2 52dd7fa — five .inc-based category pages gained "Canonical grammars". +- S3 546db11 — c_alias_analysis, biological_uniprot, rdf (union of 4) gained + the section. +- S4 1ee9f30 — 113 graph pages stripped, five .inc files deleted. +- S5 07c9a4c — templates (Category field + three cases), add-graph skill, + graphs index note. +- S6 — clean rebuild `uv run make -C docs clean html`: build succeeded under + `-W --keep-going`, zero warnings; all 8 category pages render the section + (anchor `canonical-grammars` present, rdf shows all four grammars incl. + broaderTransitive); 0 of 113 graph pages still carry it. From b544ce00d8d1b74b416f753c2fcf7a51cc7a8cfd Mon Sep 17 00:00:00 2001 From: gsv Date: Fri, 18 Sep 2026 10:18:43 +0300 Subject: [PATCH 039/277] docs(41-S7): re-point stale references at the RDF category page The whole-repo review found two descriptions that still located the RDF canonical grammars on the per-graph docs pages, where they no longer live: the RDF_GRAMMAR_TYPES comment in utils/convert_old_to_new.py and the conversion-tool paragraph in docs/utils.rst. Both now point at the RDF category page, which is where the section moved to in S3. Comment-only change; the convert tool's tests (51) pass and pre-commit is clean. --- docs/utils.rst | 6 +++--- tasks/detailed_plan.md | 20 +++++++++++++++++++- utils/convert_old_to_new.py | 6 +++--- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/docs/utils.rst b/docs/utils.rst index f909aa2b..2facab1b 100644 --- a/docs/utils.rst +++ b/docs/utils.rst @@ -157,9 +157,9 @@ shared by all new-format java archives (indexed symbols ``load``, ``store``, package canonical grammars (:func:`cfpq_data.grammars.generators.c_alias_grammar`, :func:`cfpq_data.grammars.generators.nested_parentheses_grammar` with -``eps=False`` — for RDF the three canonical grammars of the graph's docs -page, plus broaderTransitive if the graph has such edges). Reversed ``_r`` -edges are not stored; the README documents that they are derived by +``eps=False`` — for RDF the three canonical grammars documented on the RDF +category page, plus broaderTransitive if the graph has such edges). Reversed +``_r`` edges are not stored; the README documents that they are derived by reversing the respective forward edges. Behavior: diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index d96075f2..f4052d86 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -176,7 +176,25 @@ few graph pages (section gone). - Grep the build log for `grammar_*.inc` (no unresolved includes) and for dangling refs. -### S7: Mark task 41 done in the task log +### S7: Resolve code-review findings (stale references to the old location) + +**Code:** Modify `utils/convert_old_to_new.py` (comment only) and +`docs/utils.rst`. +**Tests:** `uv run pytest tests/utils/test_convert_old_to_new.py` (51 +passed); pre-commit clean on both files. +**Docs:** `docs/utils.rst` — the conversion-tool description pointed at "the +graph's docs page" for the RDF canonical grammars; it now points at the RDF +category page. + +**Spec:** +- The whole-repo review found two references to the pre-move location of the + canonical grammar descriptions: the `RDF_GRAMMAR_TYPES` comment in + `utils/convert_old_to_new.py` ("of every RDF graph page ... as on the docs + pages") and the conversion-tool paragraph in `docs/utils.rst` ("the three + canonical grammars of the graph's docs page"). Both now say "RDF category + page". No behavior change. + +### S8: Mark task 41 done in the task log **Code:** n/a. Modify `tasks/tasks.md`, `tasks/detailed_plan.md`. **Tests:** n/a. diff --git a/utils/convert_old_to_new.py b/utils/convert_old_to_new.py index 6cb37812..3ab32ae5 100644 --- a/utils/convert_old_to_new.py +++ b/utils/convert_old_to_new.py @@ -435,9 +435,9 @@ def c_alias_cnf() -> Tuple[List[Tuple[str, Tuple[str, ...]]], str]: return cnf_lite(_cfg_productions(cfg)), cfg.start_symbol.to_text() -#: The three canonical nested-parentheses grammars of every RDF graph page: -#: filename -> opening/closing label pairs (reversed edge first, as on the -#: docs pages). +#: The three canonical nested-parentheses grammars of the RDF category +#: (documented on the RDF category page): filename -> opening/closing label +#: pairs (reversed edge first, as on the category page). RDF_GRAMMAR_TYPES = { "nested_parentheses_subClassOf_type.cnf": [ ("subClassOf_r", "subClassOf"), From 408c0aa6637b95ef53eb5dbec8032ee1450d484c Mon Sep 17 00:00:00 2001 From: gsv Date: Fri, 18 Sep 2026 10:43:17 +0300 Subject: [PATCH 040/277] docs(41-S8): mark task 41 done in the task log MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All subtasks are committed and verified: the canonical grammar descriptions now live once per category on the eight category pages (the rdf page carries the union of all four grammars), the 113 per-graph pages no longer repeat them, the five .inc files are gone, and the contribution flow (templates, add-graph skill, graphs index) documents the three cases — existing category, new grammar for an existing category, new category. The quality gate passed: 363 tests, clean pre-commit and ty, zero-warning docs build, clean link check. --- tasks/detailed_plan.md | 7 +++++++ tasks/tasks.md | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index f4052d86..9a1656c0 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -218,3 +218,10 @@ category page. `-W --keep-going`, zero warnings; all 8 category pages render the section (anchor `canonical-grammars` present, rdf shows all four grammars incl. broaderTransitive); 0 of 113 graph pages still carry it. +- S7 b544ce0 — review fix: stale "graph's docs page" references re-pointed to + the RDF category page (utils/convert_old_to_new.py comment, docs/utils.rst). +- Quality gate PASS: `uv run pytest` 363 passed / 0 failed / 0 skipped; + `pre-commit run --all-files` all passed; `ty check` clean; docs build + zero warnings; linkcheck exit 0 (two Wikipedia 403 rate-limits on the first + pass cleared on retry — both URLs verified 200). +- S8 — task marked done in the task log. diff --git a/tasks/tasks.md b/tasks/tasks.md index b681b252..b1211079 100644 --- a/tasks/tasks.md +++ b/tasks/tasks.md @@ -40,4 +40,4 @@ - [done] Task 38: We use mechanism to close issues automatically described here: https://github.blog/news-insights/product-news/closing-issues-via-commit-messages/ Improve imstructions to write respective commut message when task is link to issue. - [done] Task 39: Fix https://github.com/FormalLanguageConstrainedPathQuerying/CFPQ_Data/issues/94 - [done] Task 40: For the site, add archive sizes (size to download) to tables with graphs. Add one new column to each table (for each category). Choose one unit of neasure for all graphs (Kb, Mb or Gb). Moreover, improve tool that uploads new graph. It should compute archive size. When new raph added, table must be updated. So computed size used for it. **[USER GUIDANCE]**: "Include old graphs (Recommended)" / "Add a reusable utils script" -- [ ] Task 41: Analyze structure of the site. Looks like better place for canonical grammars description is category page, not graph. Because grammar canonical for category. **[USER GUIDANCE]**: "On issue and request teplamtes. If graph for existing category, then ok. But we can have at least two more options. Graph for new category. Then grammars should be provided. New grammar for existing category." / "Nothing (Recommended)" (graph pages keep no grammar section or pointer) / "Leave as-is (Recommended)" (docs/old_graphs legacy pages untouched) / "All 4 grammars (Recommended)" (rdf category page lists the union incl. broaderTransitive) / "Yes, add it (Recommended)" (Category row in both graph templates) +- [done] Task 41: Analyze structure of the site. Looks like better place for canonical grammars description is category page, not graph. Because grammar canonical for category. **[USER GUIDANCE]**: "On issue and request teplamtes. If graph for existing category, then ok. But we can have at least two more options. Graph for new category. Then grammars should be provided. New grammar for existing category." / "Nothing (Recommended)" (graph pages keep no grammar section or pointer) / "Leave as-is (Recommended)" (docs/old_graphs legacy pages untouched) / "All 4 grammars (Recommended)" (rdf category page lists the union incl. broaderTransitive) / "Yes, add it (Recommended)" (Category row in both graph templates) From b72742ea6eda7c649e6c4b41eb940981650181e6 Mon Sep 17 00:00:00 2001 From: gsv Date: Fri, 18 Sep 2026 13:42:17 +0300 Subject: [PATCH 041/277] docs(42-S1): record task 42 and create the FLPQ design page with taxonomy Task 42 designs the extension of CFPQ_Data from context-free path queries to all classes of formal-language-constrained path querying (FLPQ). The task log records the user's description and guidance verbatim: rename to flpq_data, shared graph catalog, MCFPQ = Seki's multiple context-free languages (not a combination of CFGs) with the POPL 2025 reachability paper as reference application, Datalog-like MCFG syntax parsed with lark, reachable-pairs rendering split per category while the flat CSV stays the downloadable source of truth, incremental tasks first and no release task. The detailed plan decomposes the docs-only task into six subtasks. This commit creates docs/flpq.rst (wired into the index toctree so it is not orphaned) with the query-class taxonomy (RPQ/CFPQ/MCFPQ by language class) and the MCFP model: the d-MCFG(r) formalism in predicate notation, the hierarchy facts (CFL = 1-MCFL, TAL = 2-MCFL(2), decidable membership), and the reachability semantics where an arity-k nonterminal denotes k independent paths and the arity-1 start symbol keeps 'reachable pairs' defined exactly as for CFPQ. Verified: no-warning docs build (exit 0). --- docs/flpq.rst | 112 +++++++++++ docs/index.rst | 1 + tasks/detailed_plan.md | 426 ++++++++++++++++++++--------------------- tasks/tasks.md | 1 + 4 files changed, 325 insertions(+), 215 deletions(-) create mode 100644 docs/flpq.rst diff --git a/docs/flpq.rst b/docs/flpq.rst new file mode 100644 index 00000000..1b971141 --- /dev/null +++ b/docs/flpq.rst @@ -0,0 +1,112 @@ +.. _flpq: + +FLPQ: Formal-Language-Constrained Path Querying +=============================================== + +.. only:: html + + :Release: |release| + :Date: |today| + +Formal-language-constrained path querying (FLPQ) studies reachability in +labeled directed graphs where a path from :math:`u` to :math:`v` counts only +if its edge-label string belongs to a given formal language. CFPQ_Data +currently provides data for context-free path queries (CFPQ); it is being +extended to all classes of FLPQ: regular path queries (RPQ) and multiple +context-free path queries (MCFPQ). This page records the design decisions — +the query-class taxonomy, the grammar formalisms and file formats, and the +target structure of the site, the package, and the dataset. Implementation +happens in follow-up tasks; until then the existing CFPQ data and interfaces +remain unchanged. + +Query classes +------------- + +.. list-table:: + :header-rows: 1 + + * - Query class + - Language class + - Formalism + - Status in the dataset + * - RPQ + - Regular + - Regular expressions, NFA/DFA + - planned + * - CFPQ + - Context-free + - CFG/CNF (incl. indexed grammars) + - current + * - MCFPQ + - Multiple context-free + - MCFG (:math:`d`-MCFG(:math:`r`)) + - planned + +All three classes use the same query pattern: a language :math:`L` constrains +the paths of a labeled graph, and a pair :math:`(u, v)` is reachable if some +string of :math:`L` labels a path from :math:`u` to :math:`v`. The classes +differ only in the language class used for the constraint and in the +formalism that specifies it. The existing data — the :ref:`graphs ` +catalog, the :ref:`grammar templates `, and the +:ref:`reachable pair counts ` — is CFPQ data; the shared +graph catalog is reused by all classes. + +Multiple context-free languages +------------------------------- + +MCFPQ constraints are multiple context-free languages (MCFLs), generated by +multiple context-free grammars (MCFGs) +(`Seki et al., 1991 `_). An +MCFL is a class of languages strictly wider than the context-free languages: +an MCFG performs simultaneous context-free parsing on several substrings of a +word and can thus express bounded context-sensitivity between them. MCFLs are +mildly context-sensitive: membership is decidable, and the classes form an +infinite hierarchy parameterized by two integers. + +A multiple context-free grammar of dimension :math:`d` and rank :math:`r`, +written :math:`d`-MCFG(:math:`r`), is a tuple +:math:`\mathcal{G} = (\mathcal{N}, \Sigma, \mathcal{R}, \mathcal{S})`: + +- :math:`\mathcal{N}` — nonterminals, each denoted as a predicate + :math:`A(x_1, \dots, x_k)` of arity :math:`k \leq d`; +- :math:`\Sigma` — terminals; +- :math:`\mathcal{R}` — rules. A *basic rule* is a nonterminal + :math:`A(s_1, \dots, s_k)` with each :math:`s_i` a string of terminals + (possibly empty). A *production rule* has the form + + .. math:: + + A_0(s_1, \dots, s_{k_0}) \leftarrow + A_1(x_1^1, \dots, x_{k_1}^1), \dots, A_\ell(x_1^\ell, \dots, x_{k_\ell}^\ell) + + with :math:`\ell \leq r`, each head template + :math:`s_i \in (\Sigma \cup X)^*` over the rule's variables + :math:`X = \{x_j^i\}`, and each variable appearing at most once in + :math:`s_1 \cdots s_{k_0}`; +- :math:`\mathcal{S}` — the start nonterminal, of arity 1. + +A nonterminal of arity :math:`k` derives a *tuple* of :math:`k` strings +simultaneously; the language of the grammar is +:math:`\mathcal{L}(\mathcal{G}) = \{w \in \Sigma^* : \mathcal{S} \Rightarrow w\}`. + +The hierarchy contains the familiar classes as special levels: context-free +languages are exactly the 1-MCFLs, and tree adjoining languages (and head +languages) fall in dimension 2. Membership of a word of length :math:`n` is +decidable in :math:`O(n^{d(r+1)})` time. + +In the path-querying setting, MCFL reachability generalizes CFPQ directly +(`Conrado et al., POPL 2025 `_, +`ACM `_). On a labeled graph, an +arity-:math:`k` nonterminal denotes :math:`k` independent paths: +:math:`A[(u_1, v_1), \dots, (u_k, v_k)]` holds iff there exist paths +:math:`P_i : u_i \leadsto v_i` such that +:math:`A \Rightarrow (\lambda(P_1), \dots, \lambda(P_k))`. Because the start +symbol always has arity 1, the reachable *pairs* +:math:`\{(u, v) : \mathcal{S}[(u, v)]\}` are defined exactly as for CFPQ, so +the reference-answer data of this dataset extends to MCFPQ without changing +its meaning. All-pairs reachability is computable in +:math:`O(n^{2d+1})` time for :math:`r = 1` and +:math:`O(n^{d(r+1)})` for :math:`r > 1`. The paper's motivating application +is static program analysis: the MCFLs underapproximate interleaved Dyck +reachability — the undecidable language behind combined call-context and +field sensitivity — with tunable precision as the dimension grows. diff --git a/docs/index.rst b/docs/index.rst index bb3cb8c1..6f4b4904 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -26,6 +26,7 @@ Documentation :maxdepth: 1 getting_started + flpq dataset reference/index project diff --git a/tasks/detailed_plan.md b/tasks/detailed_plan.md index 9a1656c0..7db8df75 100644 --- a/tasks/detailed_plan.md +++ b/tasks/detailed_plan.md @@ -1,227 +1,223 @@ -# Detailed Plan: Task 41 — Move canonical grammar descriptions from graph pages to category pages - -## Task - -Analyze structure of the site. Looks like better place for canonical grammars -description is category page, not graph. Because grammar canonical for category. - -**[USER GUIDANCE]**: "On issue and request teplamtes. If graph for existing -category, then ok. But we can have at least two more options. Graph for new -category. Then grammars should be provided. New grammar for existing category." -/ "Nothing (Recommended)" (graph pages keep no grammar section or pointer) / -"Leave as-is (Recommended)" (docs/old_graphs legacy pages untouched) / -"All 4 grammars (Recommended)" (rdf category page lists the union incl. -broaderTransitive) / "Yes, add it (Recommended)" (Category row in both graph -templates) - -## Analysis (verified against the tree, 2026-09-18) - -Site layout: `docs/dataset.rst` toctree → `graphs/index` → 8 category pages -(`docs/graphs/.rst`) → 113 graph pages (`docs/graphs/data/*.rst`). -Separately, `docs/grammars/` holds 4 parameterized *template* pages -(nested_parentheses, dyck, c_alias, java_points_to) — different purpose, kept. - -7 distinct canonical grammar texts are each repeated on every graph page of -its category: - -| Category | Pages | Current duplication | -|---|---|---| -| c_alias_analysis | 20 | identical inline section (incl. `change_edges` note, 2 variants) | -| rdf | 20 | inline; 19 identical + geospecies has a 4th grammar (broaderTransitive) | -| biological_uniprot | 10 | identical inline section | -| java_points_to | 21 | inconsistent: 14 pages inline + 7 via `.. include::` | -| field_sensitive_alias | 10 | `.. include:: grammar_cpu17_field_sensitive_alias.inc` | -| context_sensitive_data_flow | 10 | `.. include:: grammar_cpu17_context_sensitive_data_flow.inc` | -| data_provenance | 18 | `.. include:: grammar_data_provenance.inc` | -| name_resolution | 4 | `.. include:: grammar_name_resolution.inc` | - -5 `.inc` files live in `docs/graphs/data/`. No tooling (utils/, tests/, -cfpq_data/) references them. Docs build is nitpicky with a no-warnings policy, -so it catches dangling refs. - -## Decisions - -- Grammar text moves **verbatim** to the category page, appended after the - per-category graph table (the table already has one column per grammar - language — the description belongs with it). -- Section heading normalized to `Canonical grammars` on all 8 category pages - (sources use "Canonical grammars" / "Canonical Grammar" / "Grammar"). -- Graph pages: section removed entirely, nothing left in its place (user - decision). The category page is the parent in the toctree/nav. -- `docs/old_graphs/` (54 legacy pages, orphan page, no category structure): - untouched (user decision). -- rdf category page: union of all 4 grammars (3 shared + broaderTransitive), - keeping the `----` separators (user decision). -- Cross-reference lines to `docs/grammars/` template pages - (`:ref:`java_points-to``, `:ref:`c_alias``, `:ref:`nested_parentheses``) - are kept — they tie the concrete canonical grammar to its parameterized - template. -- Docs-only task: no `.py` changes; code gates (tests/lint/format) skipped, - docs build gate applies. - -## Subtasks - -### S1: Record task 41 in the task log and write the detailed plan - -**Code:** n/a. Modify `tasks/tasks.md`, `tasks/detailed_plan.md`. -**Tests:** n/a. -**Docs:** n/a (task tracking files). +# Detailed Plan: Task 42 — FLPQ design document + +Task: design the structure of the site and the project for extending CFPQ_Data +to all classes of formal-language-constrained path queries (FLPQ): regular +(RPQ), context-free (CFPQ, existing), and multiple context-free (MCFPQ). +Docs-only task — no `.py` files change; code-specific gates (tests, lint, +format) are skipped per the workflow rules, but the docs build (no-warnings +policy) and the link check must pass. + +Deliverable: `docs/flpq.rst` — the single source of truth for the FLPQ design +(taxonomy, MCFG formalism, `.mcfg` format spec, target site/package/dataset +structure, migration path), linked from the index toctree so team members can +discuss it. Plus the follow-up task list in `tasks/global_plan.md`. + +Locked decisions (user guidance, recorded verbatim in `tasks/tasks.md`): +- Package renamed to `flpq_data` / PyPI `flpq-data` at 6.0.0; `cfpq-data` + becomes a thin deprecation shim. +- Graphs: shared catalog (single source of truth); per-class sections + cross-link applicable graphs. +- MCFPQ = Seki's multiple context-free languages (a language class wider than + CFL), NOT a combination of several CFGs; reference application: Conrado et + al., "Program Analysis via Multiple Context Free Language Reachability" + (ACM doi 10.1145/3704854). +- MCFGs are specified in a Datalog-like syntax (user requirement); parser + library: `lark` (verified: no off-the-shelf Datalog/MCFG text parser exists + — MCFG head templates are not standard Datalog; lark is MIT, maintained, + zero required deps). +- Reachable pairs: the flat table stays as a downloadable CSV for automatic + processing; site rendering is split into per-category tables. +- Incremental tasks first (reachable-pairs refactor, MCFG readwrite); NO + release task is planned — "We must do much more tasks first." + +Research facts used by this plan (verified 2026-09-18): +- Seki, Matsumura, Fujii, Kasami, "On multiple context-free grammars", + Theoretical Computer Science 88(2), 191–229, 1991, + doi 10.1016/0304-3975(91)90374-B — the d-MCFG(r) formalism: dimension d + bounds nonterminal arity, rank r bounds RHS nonterminals; CFL = 1-MCFL; + TAL = 2-MCFL(2); membership in O(n^{d(r+1)}). +- Conrado, Kjelstrøm, Pavlogiannis, van de Pol, "Program Analysis via Multiple + Context Free Language Reachability", POPL 2025 (arXiv 2411.06383; ACM doi + 10.1145/3704854) — Datalog-like predicate notation for MCFGs + (`A(x1, ..., xk)` predicates; basic rules `A(s1, ..., sk)`; production rules + `A0(s1, ..., sk0) <- A1(...), ..., Al(...)` with head templates mixing + terminals and variables, each variable at most once); reachability semantics: + an arity-k nonterminal denotes k independent paths, `S[(u,v)]` gives the + reachable pairs (start symbol always arity 1); O(n^{2d+1}) for r=1, + O(n^{d(r+1)}) for r>1; no public implementation (private Go tool). +- Current site: one flat ~155-row table in `docs/reachable_pairs.rst`; + per-category graph tables already carry count columns (task 28); data source + is `cfpq_data/dataset/reachable_pairs.csv` + `reachable_pairs()` API. + +### S1: Create docs/flpq.rst with the FLPQ taxonomy and model + +**Code:** none (docs-only task). +**Tests:** docs build must stay warning-free after the change (no-warnings +policy); no pytest impact. +**Docs:** new file `docs/flpq.rst` (skeleton + complete "Query classes" and +"Multiple context-free languages" sections); add `flpq` to the index toctree +in `docs/index.rst` (between `getting_started` and `dataset`) so the page is +not orphaned from the first commit. **Spec:** -- Append Task 41 to `tasks/tasks.md` with the user's description verbatim and - the `[USER GUIDANCE]` annotations. -- Write this detailed plan. - -### S2: Add "Canonical grammars" section to the 5 .inc-based category pages - -**Code:** n/a (docs-only). Modify `docs/graphs/java_points_to.rst`, -`docs/graphs/field_sensitive_alias.rst`, -`docs/graphs/context_sensitive_data_flow.rst`, -`docs/graphs/data_provenance.rst`, `docs/graphs/name_resolution.rst`. -**Tests:** n/a — verified by the docs build (S6). -**Docs:** the 5 category pages gain a `Canonical grammars` section after the -graph table, content moved verbatim from `grammar_java_points_to.inc`, -`grammar_cpu17_field_sensitive_alias.inc`, -`grammar_cpu17_context_sensitive_data_flow.inc`, -`grammar_data_provenance.inc`, `grammar_name_resolution.inc` respectively; -headings normalized to `Canonical grammars`; template-page cross-references -kept. +- Page label `.. _flpq:`, title "FLPQ: Formal-Language-Constrained Path + Querying", standard `.. only:: html` release/date header like other pages. +- Intro paragraph: FLPQ = paths of a labeled graph constrained by a formal + language; the project currently covers CFPQ and is extended to RPQ and + MCFPQ; this page records the design decisions (what/why), implementation + happens in follow-up tasks. +- "Query classes" section: list-table with columns Query class | Language + class | Formalism | Status in the dataset: + - RPQ — Regular — regular expressions, NFA/DFA — planned + - CFPQ — Context-free — CFG/CNF (incl. indexed grammars) — current + - MCFPQ — Multiple context-free (Seki) — MCFG, d-MCFG(r) — planned + Plus a paragraph: all classes share the same query pattern (a language L + constrains graph paths; (u, v) reachable iff some string of L labels a path + u -> v); they differ only in the language class and its formalism. +- "Multiple context-free languages" section: definition of d-MCFG(r) in the + predicate notation (nonterminal = predicate A(x1, ..., xk), arity k <= d; + basic rules A(s1, ..., sk) with terminal strings incl. epsilon; production + rules A0(s1, ..., sk0) <- A1(...), ..., Al(...) with l <= r, head templates + over terminals + variables, each variable at most once; start symbol arity + 1); hierarchy facts (CFL = 1-MCFL, TAL = 2-MCFL(2), mildly context-sensitive, + decidable membership O(n^{d(r+1)})); reachability semantics (arity-k + nonterminal = k independent paths; reachable pairs via the arity-1 start + symbol; complexity O(n^{2d+1}) for r=1 / O(n^{d(r+1)}) for r>1) and the + static-analysis application (underapproximating interleaved Dyck + reachability). Use :math: roles for the notation. + +### S2: Add the .mcfg grammar format spec section + +**Code:** none. +**Tests:** docs build warning-free. +**Docs:** extend `docs/flpq.rst` with a "MCFG grammar format (.mcfg)" section. **Spec:** -- Append the section at the end of each page (after the list-table), one - blank line between the table and the section header. -- Do NOT delete the `.inc` files or touch graph pages yet (S4) — the build - must stay green at every commit, and includes resolve until removed. - -### S3: Add "Canonical grammars" section to c_alias_analysis, biological_uniprot, rdf - -**Code:** n/a (docs-only). Modify `docs/graphs/c_alias_analysis.rst`, -`docs/graphs/biological_uniprot.rst`, `docs/graphs/rdf.rst`. -**Tests:** n/a — verified by the docs build (S6). -**Docs:** the 3 category pages gain a `Canonical grammars` section after the -graph table. - -**Spec:** -- c_alias_analysis: verbatim from the inline section shared by its 20 graph - pages (the `.. note::` about `change_edges`, both grammar variants with the - `----` separator, Pyformlang blocks, `:ref:`c_alias`` cross-reference). -- biological_uniprot: verbatim from the inline section shared by its 10 - unigraph pages ("The grammar file is attached to the archive." + math). -- rdf: union — the 3 grammars shared by 19 pages (combined subClassOf+type, - subClassOf-only, type-only) plus the broaderTransitive grammar from - geospecies.rst, in that order, keeping the `----` separators and the - `:ref:`nested_parentheses`` cross-reference. - -### S4: Remove grammar sections from all 113 graph pages; delete the .inc files - -**Code:** n/a (docs-only). Modify all 113 `docs/graphs/data/*.rst` pages; -delete `docs/graphs/data/grammar_java_points_to.inc`, -`grammar_cpu17_field_sensitive_alias.inc`, -`grammar_cpu17_context_sensitive_data_flow.inc`, -`grammar_data_provenance.inc`, `grammar_name_resolution.inc`. -**Tests:** n/a — verified by the docs build (S6). -**Docs:** graph pages lose their trailing grammar section; no replacement -text (user decision). - -**Spec:** -- 64 pages carry the section inline (header at line start: `Canonical - grammars` or `Grammar`, section runs to EOF): delete from the header line - to EOF, leaving the file ending with the Edges Statistics table and a - single trailing newline. -- 49 pages end with a blank line + `.. include:: grammar_*.inc`: delete both - lines. -- Verify afterwards: no `include::` left in `docs/graphs/`, no page starts a - section with `^Canonical|^Grammar`, and the 5 `.inc` files are gone. -- `docs/old_graphs/` untouched. - -### S5: Update contribution templates, add-graph skill, graphs index note - -**Code:** n/a (docs-only). Modify -`.github/PULL_REQUEST_TEMPLATE/new_graph.md`, -`.github/ISSUE_TEMPLATE/graph-add-template.md`, -`.opencode/skills/add-graph/SKILL.md`, `docs/graphs/index.rst`. -**Tests:** n/a. -**Docs:** templates + skill + index note per spec. +- State the design decision: Datalog-like syntax per Conrado et al.'s + predicate notation (user requirement); rationale for the parser choice — + verified that no off-the-shelf library parses this syntax (PyPI `datalog` is + a hardware ADC lib; `pyDatalog` is an engine without a documented text + parser and standard Datalog heads cannot express MCFG head templates; no + MCFG/MCFL library exists) — therefore `lark` (MIT, maintained, zero + required deps) with the EBNF grammar doubling as executable format + documentation. +- Lexical conventions (one rule per line; blank lines and `#` comments + ignored): nonterminals = identifiers starting with an uppercase letter; + terminals = edge labels verbatim; variables = `x` followed by digits + (x1, x2, ...), a terminal must never match this pattern; epsilon = the + token `eps`; arrow = `<-`. +- Rule forms: basic rule `A(s1, ..., sk)` (arguments are space-separated + terminal tokens or `eps`); production rule + `A0(s1, ..., sk0) <- A1(x...), ..., Al(x...)` (body atoms carry variables + only). +- Validation constraints enforced by the reader: arity consistency per + nonterminal; all body variables pairwise distinct; each body variable + appears exactly once across the head templates (no dangling variables — + stricter than the minimal definition, satisfied by all published examples); + start symbol defaults to `S`, must have arity 1, overridable via an API + parameter (consistent with the existing cnf/cfg/rsa readers). +- Dimension d and rank r are computed from the rules (max arity / max body + atoms) and reported by the reader — no header to keep in sync. +- Two worked examples in code blocks: the paper's 2-MCFG(2) for + L = {w1 w2 # w2 w1 | w1, w2 in {0,1}*} (A(eps, eps); A(x1 0, x2 0) <- + A(x1, x2); A(x1 1, x2 1) <- A(x1, x2); S(x1 y1 # y2 x2) <- A(x1, x2), + A(y1, y2)) and a d=1 CFG embedding for {0^n 1^n 1^m 0^m} showing the format + subsumes CFGs. +- Relationship to existing formats: CFPQ data stays `.cnf` (pyformlang + ecosystem, no re-upload); MCFPQ uses `.mcfg`; a `.cnf <-> .mcfg` converter + is a follow-up task; RPQ keeps regex text files. + +### S3: Add the site structure design section + +**Code:** none. +**Tests:** docs build warning-free. +**Docs:** extend `docs/flpq.rst` with a "Site structure" section. **Spec:** -- Both templates: add a `Category` row to the Info table — value is the - existing category name, or `new: `. -- Both templates: replace the "Canonical grammars" section with the three-case - structure: (1) graph for an existing category — name the grammar(s) from - the category's "Canonical grammars" section that apply; they become the - table column(s) filled in for the new row; no new grammar text. (2) New - grammar for an existing category — provide LaTeX + Pyformlang below; it is - added to the category page and a new column to its table. (3) Graph for a - new category — provide the canonical grammar(s) below; a new category page - is created with them. The LaTeX/Pyformlang placeholders apply to cases 2–3 - only. -- add-graph skill Documentation step: per-graph pages no longer carry a - grammar section; describe the three cases (row under an existing column / - add grammar + column to the category page / new category page with grammar, - table, and `docs/graphs/index.rst` registration). -- `docs/graphs/index.rst` "Contents" section: one sentence stating that - canonical grammars are documented on the category pages. - -### S6: Docs build verification - -**Code:** n/a. -**Tests:** full Sphinx build per the build-docs skill; zero warnings -(no-warnings policy); no new "not included in any toctree" warnings; spot-check -rendered HTML of the 8 category pages (section present, math rendered) and a -few graph pages (section gone). -**Docs:** n/a. +- Target hierarchy (code block): Dataset -> Graphs (shared catalog, 8 + categories, unchanged) + one section per query class (CFPQ / RPQ / MCFPQ), + each with its Grammars/Queries templates page, Benchmarks, and a list of + applicable graphs (cross-links, no duplication); Reachable pairs page at + the Dataset level. Note the navigation depth: conf.py `navigation_depth` is + 3, which accommodates section -> class -> template pages. +- Reachable-pairs rendering design: the flat table is removed from + `docs/reachable_pairs.rst`; the page renders one table per graph category + (columns Graph | Grammar | Reachable pairs); the CSV remains the single + source of truth for automatic processing and gains a `category` column; a + utils generator script (pattern of `utils/archive_sizes.py`) renders both + the per-category tables and the category-page count columns from the CSV so + no numbers are hand-maintained in two places. + +### S4: Add the package structure and API design section + +**Code:** none. +**Tests:** docs build warning-free. +**Docs:** extend `docs/flpq.rst` with a "Package structure" section. **Spec:** -- Build must exit clean under the project's no-warnings configuration. -- Grep the build log for `grammar_*.inc` (no unresolved includes) and for - dangling refs. - -### S7: Resolve code-review findings (stale references to the old location) - -**Code:** Modify `utils/convert_old_to_new.py` (comment only) and -`docs/utils.rst`. -**Tests:** `uv run pytest tests/utils/test_convert_old_to_new.py` (51 -passed); pre-commit clean on both files. -**Docs:** `docs/utils.rst` — the conversion-tool description pointed at "the -graph's docs page" for the RDF canonical grammars; it now points at the RDF -category page. +- Target layout (code block): `flpq_data/` with `config.py`, `dataset/` + (download machinery + per-class registries + reachable_pairs), `graphs/` + (unchanged, class-agnostic I/O), and `queries/` (renamed from `grammars/`) + containing `cfpq/` (existing generators/readwrite{cfg,cnf,cnf_template}/ + converters/utils), `rpq/` (regex + rsa readwrite moved here; new + regex-template generators), `mcfpq/` (new lark-based mcfg readwrite; + generators). +- Interim placement before the rename: MCFG readwrite lands in + `cfpq_data/grammars/readwrite/mcfg.py` (formalism-based module convention, + alongside `regex.py` and `rsa.py`) so no global rework is needed to start. +- API changes: `download(name)` -> `download_graph(name)`; + `download_grammars(template, graph_name=None)` -> + `download_query(query_class, template, graph_name=None)`; old names kept as + deprecated aliases; registries `DATASET` -> `GRAPHS`, + `GRAMMAR_TEMPLATES` -> per-class `CFPQ_TEMPLATES` / `RPQ_TEMPLATES` / + `MCFPQ_TEMPLATES`; `reachable_pairs()` gains the category field. +- Distribution: new PyPI project `flpq-data` at 6.0.0; `cfpq-data` 6.0.0 is a + thin shim depending on `flpq-data`, re-exporting the old names with + DeprecationWarning. + +### S5: Add the dataset layout + migration path; write the follow-up task list + +**Code:** none. +**Tests:** docs build warning-free. +**Docs:** extend `docs/flpq.rst` with a "Dataset layout and migration" +section; rewrite `tasks/global_plan.md` with the follow-up task list. **Spec:** -- The whole-repo review found two references to the pre-move location of the - canonical grammar descriptions: the `RDF_GRAMMAR_TYPES` comment in - `utils/convert_old_to_new.py` ("of every RDF graph page ... as on the docs - pages") and the conversion-tool paragraph in `docs/utils.rst` ("the three - canonical grammars of the graph's docs page"). Both now say "RDF category - page". No behavior change. - -### S8: Mark task 41 done in the task log - -**Code:** n/a. Modify `tasks/tasks.md`, `tasks/detailed_plan.md`. -**Tests:** n/a. -**Docs:** n/a (task tracking files). +- Target S3 layout under the 6.0.0 prefix (code block): + `graph/.tar.gz` (shared, copied from 5.0.0); + `query/{cfpq,rpq,mcfpq}/