From 10e36db085997e7f85ab1117d7c0d4976eb8db1c Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Sun, 21 Dec 2025 14:54:54 -0500 Subject: [PATCH 01/19] Outline of floris integration --- .gitignore | 4 +- MITRotor/FlorisInterface.py | 77 ++ poetry.lock | 1925 ++++++++++++++--------------------- pyproject.toml | 3 +- 4 files changed, 854 insertions(+), 1155 deletions(-) create mode 100644 MITRotor/FlorisInterface.py diff --git a/.gitignore b/.gitignore index e626d6f..f729f42 100644 --- a/.gitignore +++ b/.gitignore @@ -187,4 +187,6 @@ poetry.toml # LSP config files pyrightconfig.json -# End of https://www.toptal.com/developers/gitignore/api/python \ No newline at end of file +# End of https://www.toptal.com/developers/gitignore/api/python + +.DS_Store \ No newline at end of file diff --git a/MITRotor/FlorisInterface.py b/MITRotor/FlorisInterface.py new file mode 100644 index 0000000..54da501 --- /dev/null +++ b/MITRotor/FlorisInterface.py @@ -0,0 +1,77 @@ +import numpy as np +from attrs import define, field +from typing import Literal +# FLORIS Imports +from floris.type_dec import floris_float_type, NDArrayFloat +from floris.core.turbine.operation_models import BaseOperationModel +# MITRotor Imports +from MITRotor.ReferenceTurbines import IEA15MW +from MITRotor.RotorDefinition import RotorDefinition +from MITRotor.Geometry import BEMGeometry +from MITRotor.Momentum import UnifiedMomentum +from MITRotor.BEMSolver import BEM, BEMSolution + +@define +class MITRotorTurbine(BaseOperationModel): + """ + A turbine operation model that calls MITRotor. + """ + # user can define a BEM model if they want a different rotor, momentum model, or geometry + default_bem = BEM( + rotor=IEA15MW(), + momentum_model = UnifiedMomentum(averaging = "rotor"), + geometry = BEMGeometry(Nr = 10, Ntheta = 20), + ) + bem_model = field(init = False, default = default_bem, type = BEM) + # save most recent solution by unique floris arguments + _bem_solution: BEMSolution = field(init=False, default=None) + _last_key: bytes = field(init=False, default=None) + + def _get_solution_key(self, velocities: np.ndarray) -> bytes: # TODO: add more inputs + # Fast, deterministic, and explicit + return velocities.tobytes() + + def _get_solution(self, + power_thrust_table, + velocities, + air_density=None, + ): + # create cache key for current inputs + key = self._velocity_key(velocities) # TODO: add more inputs + # update solution if conditions are different + if key != self._last_key: + self._bem_solution = self.bem_model( # TODO: make sure these inputs are right + power_thrust_table, + velocities, + air_density, + ) + self._last_key = key + return self._bem_solution + + def power( + self, + velocities: NDArrayFloat, + turbulence_intensities: NDArrayFloat, + yaw_angles: NDArrayFloat, + tilt_angles: NDArrayFloat, + **_ + ) -> NDArrayFloat: + return self._get_solution( + power_thrust_table, velocities, air_density + ).power + + + def thrust_coefficient( + self, + velocities: NDArrayFloat, + **_ + ) -> NDArrayFloat: + return self._get_solution(power_thrust_table, velocities, air_density).power + + + def axial_induction( + self, + velocities: NDArrayFloat, + **_ + ) -> NDArrayFloat: + return self._get_solution(power_thrust_table, velocities, air_density).power \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 5ab5738..b1ad6e6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,29 +1,5 @@ # This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. -[[package]] -name = "anyio" -version = "4.5.2" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "anyio-4.5.2-py3-none-any.whl", hash = "sha256:c011ee36bc1e8ba40e5a81cb9df91925c218fe9b778554e0b56a21e1b5d4716f"}, - {file = "anyio-4.5.2.tar.gz", hash = "sha256:23009af4ed04ce05991845451e11ef02fc7c5ed29179ac9a420e5ad0ac7ddc5b"}, -] - -[package.dependencies] -exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} - -[package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1) ; python_version >= \"3.10\"", "uvloop (>=0.21.0b1) ; platform_python_implementation == \"CPython\" and platform_system != \"Windows\""] -trio = ["trio (>=0.26.1)"] - [[package]] name = "anyio" version = "4.11.0" @@ -31,13 +7,13 @@ description = "High-level concurrency and networking framework on top of asyncio optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc"}, {file = "anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4"}, ] [package.dependencies] +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} @@ -52,7 +28,7 @@ description = "Disable App Nap on macOS >= 10.9" optional = false python-versions = ">=3.6" groups = ["dev"] -markers = "sys_platform == \"darwin\" and python_version <= \"3.11\" or platform_system == \"Darwin\"" +markers = "platform_system == \"Darwin\" or sys_platform == \"darwin\" and python_version < \"3.11\"" files = [ {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, @@ -73,45 +49,6 @@ files = [ [package.dependencies] argon2-cffi-bindings = "*" -[[package]] -name = "argon2-cffi-bindings" -version = "21.2.0" -description = "Low-level CFFI bindings for Argon2" -optional = false -python-versions = ">=3.6" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f"}, - {file = "argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3e385d1c39c520c08b53d63300c3ecc28622f076f4c2b0e6d7e796e9f6502194"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3e3cc67fdb7d82c4718f19b4e7a87123caf8a93fde7e23cf66ac0337d3cb3f"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a22ad9800121b71099d0fb0a65323810a15f2e292f2ba450810a7316e128ee5"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9f8b450ed0547e3d473fdc8612083fd08dd2120d6ac8f73828df9b7d45bb351"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:93f9bf70084f97245ba10ee36575f0c3f1e7d7724d67d8e5b08e61787c320ed7"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3b9ef65804859d335dc6b31582cad2c5166f0c3e7975f324d9ffaa34ee7e6583"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4966ef5848d820776f5f562a7d45fdd70c2f330c961d0d745b784034bd9f48d"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ef543a89dee4db46a1a6e206cd015360e5a75822f76df533845c3cbaf72670"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a"}, -] - -[package.dependencies] -cffi = ">=1.0.1" - -[package.extras] -dev = ["cogapp", "pre-commit", "pytest", "wheel"] -tests = ["pytest"] - [[package]] name = "argon2-cffi-bindings" version = "25.1.0" @@ -119,7 +56,6 @@ description = "Low-level CFFI bindings for Argon2" optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:3d3f05610594151994ca9ccb3c771115bdb4daef161976a266f0dd8aa9996b8f"}, {file = "argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8b8efee945193e667a396cbc7b4fb7d357297d6234d30a489905d96caabde56b"}, @@ -168,7 +104,6 @@ files = [ ] [package.dependencies] -"backports.zoneinfo" = {version = "0.2.1", markers = "python_version < \"3.9\""} python-dateutil = ">=2.7.0" tzdata = {version = "*", markers = "python_version >= \"3.9\""} @@ -192,22 +127,6 @@ files = [ astroid = ["astroid (>=2,<4)"] test = ["astroid (>=2,<4)", "pytest", "pytest-cov", "pytest-xdist"] -[[package]] -name = "async-lru" -version = "2.0.4" -description = "Simple LRU cache for asyncio" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "async-lru-2.0.4.tar.gz", hash = "sha256:b8a59a5df60805ff63220b2a0c5b5393da5521b113cd5465a44eb037d81a5627"}, - {file = "async_lru-2.0.4-py3-none-any.whl", hash = "sha256:ff02944ce3c288c5be660c42dbcca0742b32c3b279d6dceda655190240b99224"}, -] - -[package.dependencies] -typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} - [[package]] name = "async-lru" version = "2.0.5" @@ -215,32 +134,13 @@ description = "Simple LRU cache for asyncio" optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "async_lru-2.0.5-py3-none-any.whl", hash = "sha256:ab95404d8d2605310d345932697371a5f40def0487c03d6d0ad9138de52c9943"}, {file = "async_lru-2.0.5.tar.gz", hash = "sha256:481d52ccdd27275f42c43a928b4a50c3bfb2d67af4e78b170e3e0bb39c66e5bb"}, ] -[[package]] -name = "attrs" -version = "25.3.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3"}, - {file = "attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b"}, -] - -[package.extras] -benchmark = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] -cov = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] -dev = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier"] -tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\""] +[package.dependencies] +typing_extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} [[package]] name = "attrs" @@ -248,8 +148,7 @@ version = "25.4.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.9" -groups = ["dev"] -markers = "python_version >= \"3.12\"" +groups = ["main", "dev"] files = [ {file = "attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373"}, {file = "attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11"}, @@ -267,9 +166,6 @@ files = [ {file = "babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d"}, ] -[package.dependencies] -pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} - [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\""] @@ -280,42 +176,12 @@ description = "Specifications for callback functions passed in to an API" optional = false python-versions = "*" groups = ["dev"] -markers = "python_version <= \"3.11\"" +markers = "python_version < \"3.11\"" files = [ {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] -[[package]] -name = "backports-zoneinfo" -version = "0.2.1" -description = "Backport of the standard library zoneinfo module" -optional = false -python-versions = ">=3.6" -groups = ["dev"] -markers = "python_version == \"3.8\"" -files = [ - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win32.whl", hash = "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win32.whl", hash = "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6"}, - {file = "backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"}, -] - -[package.extras] -tzdata = ["tzdata"] - [[package]] name = "beautifulsoup4" version = "4.14.2" @@ -395,7 +261,7 @@ description = "An easy safelist-based HTML-sanitizing tool." optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "python_version <= \"3.11\"" +markers = "python_version < \"3.11\"" files = [ {file = "bleach-6.1.0-py3-none-any.whl", hash = "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6"}, {file = "bleach-6.1.0.tar.gz", hash = "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe"}, @@ -416,7 +282,7 @@ description = "An easy safelist-based HTML-sanitizing tool." optional = false python-versions = ">=3.10" groups = ["dev"] -markers = "python_version >= \"3.12\"" +markers = "python_version >= \"3.11\"" files = [ {file = "bleach-6.3.0-py3-none-any.whl", hash = "sha256:fe10ec77c93ddf3d13a73b035abaac7a9f5e436513864ccdad516693213c65d6"}, {file = "bleach-6.3.0.tar.gz", hash = "sha256:6f3b91b1c0a02bb9a78b5a454c92506aa0fdf197e1d5e114d2e00c6f64306d22"}, @@ -441,87 +307,6 @@ files = [ {file = "certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43"}, ] -[[package]] -name = "cffi" -version = "1.17.1" -description = "Foreign Function Interface for Python calling C code." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, - {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, - {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, - {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, - {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, - {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, - {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, - {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, - {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, - {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, - {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, - {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, - {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, - {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, - {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, - {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, -] - -[package.dependencies] -pycparser = "*" - [[package]] name = "cffi" version = "2.0.0" @@ -529,7 +314,6 @@ description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" 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"}, @@ -750,7 +534,7 @@ description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" groups = ["dev"] -markers = "python_version <= \"3.11\"" +markers = "python_version < \"3.11\"" files = [ {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, @@ -766,7 +550,7 @@ description = "Composable command line interface toolkit" optional = false python-versions = ">=3.10" groups = ["dev"] -markers = "python_version >= \"3.12\"" +markers = "python_version >= \"3.11\"" files = [ {file = "click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc"}, {file = "click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4"}, @@ -788,6 +572,24 @@ files = [ ] markers = {main = "platform_system == \"Windows\"", dev = "platform_system == \"Windows\" or sys_platform == \"win32\"", examples = "platform_system == \"Windows\""} +[[package]] +name = "coloredlogs" +version = "15.0.1" +description = "Colored terminal output for Python's logging module" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +groups = ["main"] +files = [ + {file = "coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934"}, + {file = "coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0"}, +] + +[package.dependencies] +humanfriendly = ">=9.1" + +[package.extras] +cron = ["capturer (>=2.4)"] + [[package]] name = "comm" version = "0.2.3" @@ -805,76 +607,89 @@ test = ["pytest"] [[package]] name = "contourpy" -version = "1.1.1" +version = "1.3.0" description = "Python library for calculating contours of 2D quadrilateral grids" optional = false -python-versions = ">=3.8" -groups = ["examples"] -markers = "python_version <= \"3.11\"" +python-versions = ">=3.9" +groups = ["main", "examples"] +markers = "python_version < \"3.11\"" files = [ - {file = "contourpy-1.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:46e24f5412c948d81736509377e255f6040e94216bf1a9b5ea1eaa9d29f6ec1b"}, - {file = "contourpy-1.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e48694d6a9c5a26ee85b10130c77a011a4fedf50a7279fa0bdaf44bafb4299d"}, - {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a66045af6cf00e19d02191ab578a50cb93b2028c3eefed999793698e9ea768ae"}, - {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ebf42695f75ee1a952f98ce9775c873e4971732a87334b099dde90b6af6a916"}, - {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6aec19457617ef468ff091669cca01fa7ea557b12b59a7908b9474bb9674cf0"}, - {file = "contourpy-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:462c59914dc6d81e0b11f37e560b8a7c2dbab6aca4f38be31519d442d6cde1a1"}, - {file = "contourpy-1.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6d0a8efc258659edc5299f9ef32d8d81de8b53b45d67bf4bfa3067f31366764d"}, - {file = "contourpy-1.1.1-cp310-cp310-win32.whl", hash = "sha256:d6ab42f223e58b7dac1bb0af32194a7b9311065583cc75ff59dcf301afd8a431"}, - {file = "contourpy-1.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:549174b0713d49871c6dee90a4b499d3f12f5e5f69641cd23c50a4542e2ca1eb"}, - {file = "contourpy-1.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:407d864db716a067cc696d61fa1ef6637fedf03606e8417fe2aeed20a061e6b2"}, - {file = "contourpy-1.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe80c017973e6a4c367e037cb31601044dd55e6bfacd57370674867d15a899b"}, - {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e30aaf2b8a2bac57eb7e1650df1b3a4130e8d0c66fc2f861039d507a11760e1b"}, - {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3de23ca4f381c3770dee6d10ead6fff524d540c0f662e763ad1530bde5112532"}, - {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:566f0e41df06dfef2431defcfaa155f0acfa1ca4acbf8fd80895b1e7e2ada40e"}, - {file = "contourpy-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b04c2f0adaf255bf756cf08ebef1be132d3c7a06fe6f9877d55640c5e60c72c5"}, - {file = "contourpy-1.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d0c188ae66b772d9d61d43c6030500344c13e3f73a00d1dc241da896f379bb62"}, - {file = "contourpy-1.1.1-cp311-cp311-win32.whl", hash = "sha256:0683e1ae20dc038075d92e0e0148f09ffcefab120e57f6b4c9c0f477ec171f33"}, - {file = "contourpy-1.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:8636cd2fc5da0fb102a2504fa2c4bea3cbc149533b345d72cdf0e7a924decc45"}, - {file = "contourpy-1.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:560f1d68a33e89c62da5da4077ba98137a5e4d3a271b29f2f195d0fba2adcb6a"}, - {file = "contourpy-1.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24216552104ae8f3b34120ef84825400b16eb6133af2e27a190fdc13529f023e"}, - {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56de98a2fb23025882a18b60c7f0ea2d2d70bbbcfcf878f9067234b1c4818442"}, - {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:07d6f11dfaf80a84c97f1a5ba50d129d9303c5b4206f776e94037332e298dda8"}, - {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1eaac5257a8f8a047248d60e8f9315c6cff58f7803971170d952555ef6344a7"}, - {file = "contourpy-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19557fa407e70f20bfaba7d55b4d97b14f9480856c4fb65812e8a05fe1c6f9bf"}, - {file = "contourpy-1.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:081f3c0880712e40effc5f4c3b08feca6d064cb8cfbb372ca548105b86fd6c3d"}, - {file = "contourpy-1.1.1-cp312-cp312-win32.whl", hash = "sha256:059c3d2a94b930f4dafe8105bcdc1b21de99b30b51b5bce74c753686de858cb6"}, - {file = "contourpy-1.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:f44d78b61740e4e8c71db1cf1fd56d9050a4747681c59ec1094750a658ceb970"}, - {file = "contourpy-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:70e5a10f8093d228bb2b552beeb318b8928b8a94763ef03b858ef3612b29395d"}, - {file = "contourpy-1.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8394e652925a18ef0091115e3cc191fef350ab6dc3cc417f06da66bf98071ae9"}, - {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bd5680f844c3ff0008523a71949a3ff5e4953eb7701b28760805bc9bcff217"}, - {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66544f853bfa85c0d07a68f6c648b2ec81dafd30f272565c37ab47a33b220684"}, - {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0c02b75acfea5cab07585d25069207e478d12309557f90a61b5a3b4f77f46ce"}, - {file = "contourpy-1.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41339b24471c58dc1499e56783fedc1afa4bb018bcd035cfb0ee2ad2a7501ef8"}, - {file = "contourpy-1.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f29fb0b3f1217dfe9362ec55440d0743fe868497359f2cf93293f4b2701b8251"}, - {file = "contourpy-1.1.1-cp38-cp38-win32.whl", hash = "sha256:f9dc7f933975367251c1b34da882c4f0e0b2e24bb35dc906d2f598a40b72bfc7"}, - {file = "contourpy-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:498e53573e8b94b1caeb9e62d7c2d053c263ebb6aa259c81050766beb50ff8d9"}, - {file = "contourpy-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ba42e3810999a0ddd0439e6e5dbf6d034055cdc72b7c5c839f37a7c274cb4eba"}, - {file = "contourpy-1.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6c06e4c6e234fcc65435223c7b2a90f286b7f1b2733058bdf1345d218cc59e34"}, - {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca6fab080484e419528e98624fb5c4282148b847e3602dc8dbe0cb0669469887"}, - {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93df44ab351119d14cd1e6b52a5063d3336f0754b72736cc63db59307dabb718"}, - {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eafbef886566dc1047d7b3d4b14db0d5b7deb99638d8e1be4e23a7c7ac59ff0f"}, - {file = "contourpy-1.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efe0fab26d598e1ec07d72cf03eaeeba8e42b4ecf6b9ccb5a356fde60ff08b85"}, - {file = "contourpy-1.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f08e469821a5e4751c97fcd34bcb586bc243c39c2e39321822060ba902eac49e"}, - {file = "contourpy-1.1.1-cp39-cp39-win32.whl", hash = "sha256:bfc8a5e9238232a45ebc5cb3bfee71f1167064c8d382cadd6076f0d51cff1da0"}, - {file = "contourpy-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:c84fdf3da00c2827d634de4fcf17e3e067490c4aea82833625c4c8e6cdea0887"}, - {file = "contourpy-1.1.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:229a25f68046c5cf8067d6d6351c8b99e40da11b04d8416bf8d2b1d75922521e"}, - {file = "contourpy-1.1.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a10dab5ea1bd4401c9483450b5b0ba5416be799bbd50fc7a6cc5e2a15e03e8a3"}, - {file = "contourpy-1.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4f9147051cb8fdb29a51dc2482d792b3b23e50f8f57e3720ca2e3d438b7adf23"}, - {file = "contourpy-1.1.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a75cc163a5f4531a256f2c523bd80db509a49fc23721b36dd1ef2f60ff41c3cb"}, - {file = "contourpy-1.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b53d5769aa1f2d4ea407c65f2d1d08002952fac1d9e9d307aa2e1023554a163"}, - {file = "contourpy-1.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11b836b7dbfb74e049c302bbf74b4b8f6cb9d0b6ca1bf86cfa8ba144aedadd9c"}, - {file = "contourpy-1.1.1.tar.gz", hash = "sha256:96ba37c2e24b7212a77da85004c38e7c4d155d3e72a45eeaf22c1f03f607e8ab"}, + {file = "contourpy-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:880ea32e5c774634f9fcd46504bf9f080a41ad855f4fef54f5380f5133d343c7"}, + {file = "contourpy-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:76c905ef940a4474a6289c71d53122a4f77766eef23c03cd57016ce19d0f7b42"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92f8557cbb07415a4d6fa191f20fd9d2d9eb9c0b61d1b2f52a8926e43c6e9af7"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36f965570cff02b874773c49bfe85562b47030805d7d8360748f3eca570f4cab"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cacd81e2d4b6f89c9f8a5b69b86490152ff39afc58a95af002a398273e5ce589"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69375194457ad0fad3a839b9e29aa0b0ed53bb54db1bfb6c3ae43d111c31ce41"}, + {file = "contourpy-1.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a52040312b1a858b5e31ef28c2e865376a386c60c0e248370bbea2d3f3b760d"}, + {file = "contourpy-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3faeb2998e4fcb256542e8a926d08da08977f7f5e62cf733f3c211c2a5586223"}, + {file = "contourpy-1.3.0-cp310-cp310-win32.whl", hash = "sha256:36e0cff201bcb17a0a8ecc7f454fe078437fa6bda730e695a92f2d9932bd507f"}, + {file = "contourpy-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:87ddffef1dbe5e669b5c2440b643d3fdd8622a348fe1983fad7a0f0ccb1cd67b"}, + {file = "contourpy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fa4c02abe6c446ba70d96ece336e621efa4aecae43eaa9b030ae5fb92b309ad"}, + {file = "contourpy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:834e0cfe17ba12f79963861e0f908556b2cedd52e1f75e6578801febcc6a9f49"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbc4c3217eee163fa3984fd1567632b48d6dfd29216da3ded3d7b844a8014a66"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4865cd1d419e0c7a7bf6de1777b185eebdc51470800a9f42b9e9decf17762081"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:303c252947ab4b14c08afeb52375b26781ccd6a5ccd81abcdfc1fafd14cf93c1"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637f674226be46f6ba372fd29d9523dd977a291f66ab2a74fbeb5530bb3f445d"}, + {file = "contourpy-1.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:76a896b2f195b57db25d6b44e7e03f221d32fe318d03ede41f8b4d9ba1bff53c"}, + {file = "contourpy-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e1fd23e9d01591bab45546c089ae89d926917a66dceb3abcf01f6105d927e2cb"}, + {file = "contourpy-1.3.0-cp311-cp311-win32.whl", hash = "sha256:d402880b84df3bec6eab53cd0cf802cae6a2ef9537e70cf75e91618a3801c20c"}, + {file = "contourpy-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:6cb6cc968059db9c62cb35fbf70248f40994dfcd7aa10444bbf8b3faeb7c2d67"}, + {file = "contourpy-1.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:570ef7cf892f0afbe5b2ee410c507ce12e15a5fa91017a0009f79f7d93a1268f"}, + {file = "contourpy-1.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:da84c537cb8b97d153e9fb208c221c45605f73147bd4cadd23bdae915042aad6"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0be4d8425bfa755e0fd76ee1e019636ccc7c29f77a7c86b4328a9eb6a26d0639"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c0da700bf58f6e0b65312d0a5e695179a71d0163957fa381bb3c1f72972537c"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb8b141bb00fa977d9122636b16aa67d37fd40a3d8b52dd837e536d64b9a4d06"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3634b5385c6716c258d0419c46d05c8aa7dc8cb70326c9a4fb66b69ad2b52e09"}, + {file = "contourpy-1.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0dce35502151b6bd35027ac39ba6e5a44be13a68f55735c3612c568cac3805fd"}, + {file = "contourpy-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aea348f053c645100612b333adc5983d87be69acdc6d77d3169c090d3b01dc35"}, + {file = "contourpy-1.3.0-cp312-cp312-win32.whl", hash = "sha256:90f73a5116ad1ba7174341ef3ea5c3150ddf20b024b98fb0c3b29034752c8aeb"}, + {file = "contourpy-1.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:b11b39aea6be6764f84360fce6c82211a9db32a7c7de8fa6dd5397cf1d079c3b"}, + {file = "contourpy-1.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3e1c7fa44aaae40a2247e2e8e0627f4bea3dd257014764aa644f319a5f8600e3"}, + {file = "contourpy-1.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:364174c2a76057feef647c802652f00953b575723062560498dc7930fc9b1cb7"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32b238b3b3b649e09ce9aaf51f0c261d38644bdfa35cbaf7b263457850957a84"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d51fca85f9f7ad0b65b4b9fe800406d0d77017d7270d31ec3fb1cc07358fdea0"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:732896af21716b29ab3e988d4ce14bc5133733b85956316fb0c56355f398099b"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d73f659398a0904e125280836ae6f88ba9b178b2fed6884f3b1f95b989d2c8da"}, + {file = "contourpy-1.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c6c7c2408b7048082932cf4e641fa3b8ca848259212f51c8c59c45aa7ac18f14"}, + {file = "contourpy-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f317576606de89da6b7e0861cf6061f6146ead3528acabff9236458a6ba467f8"}, + {file = "contourpy-1.3.0-cp313-cp313-win32.whl", hash = "sha256:31cd3a85dbdf1fc002280c65caa7e2b5f65e4a973fcdf70dd2fdcb9868069294"}, + {file = "contourpy-1.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:4553c421929ec95fb07b3aaca0fae668b2eb5a5203d1217ca7c34c063c53d087"}, + {file = "contourpy-1.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:345af746d7766821d05d72cb8f3845dfd08dd137101a2cb9b24de277d716def8"}, + {file = "contourpy-1.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3bb3808858a9dc68f6f03d319acd5f1b8a337e6cdda197f02f4b8ff67ad2057b"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:420d39daa61aab1221567b42eecb01112908b2cab7f1b4106a52caaec8d36973"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d63ee447261e963af02642ffcb864e5a2ee4cbfd78080657a9880b8b1868e18"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:167d6c890815e1dac9536dca00828b445d5d0df4d6a8c6adb4a7ec3166812fa8"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:710a26b3dc80c0e4febf04555de66f5fd17e9cf7170a7b08000601a10570bda6"}, + {file = "contourpy-1.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:75ee7cb1a14c617f34a51d11fa7524173e56551646828353c4af859c56b766e2"}, + {file = "contourpy-1.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:33c92cdae89ec5135d036e7218e69b0bb2851206077251f04a6c4e0e21f03927"}, + {file = "contourpy-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a11077e395f67ffc2c44ec2418cfebed032cd6da3022a94fc227b6faf8e2acb8"}, + {file = "contourpy-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e8134301d7e204c88ed7ab50028ba06c683000040ede1d617298611f9dc6240c"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e12968fdfd5bb45ffdf6192a590bd8ddd3ba9e58360b29683c6bb71a7b41edca"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fd2a0fc506eccaaa7595b7e1418951f213cf8255be2600f1ea1b61e46a60c55f"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4cfb5c62ce023dfc410d6059c936dcf96442ba40814aefbfa575425a3a7f19dc"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68a32389b06b82c2fdd68276148d7b9275b5f5cf13e5417e4252f6d1a34f72a2"}, + {file = "contourpy-1.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:94e848a6b83da10898cbf1311a815f770acc9b6a3f2d646f330d57eb4e87592e"}, + {file = "contourpy-1.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d78ab28a03c854a873787a0a42254a0ccb3cb133c672f645c9f9c8f3ae9d0800"}, + {file = "contourpy-1.3.0-cp39-cp39-win32.whl", hash = "sha256:81cb5ed4952aae6014bc9d0421dec7c5835c9c8c31cdf51910b708f548cf58e5"}, + {file = "contourpy-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:14e262f67bd7e6eb6880bc564dcda30b15e351a594657e55b7eec94b6ef72843"}, + {file = "contourpy-1.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fe41b41505a5a33aeaed2a613dccaeaa74e0e3ead6dd6fd3a118fb471644fd6c"}, + {file = "contourpy-1.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eca7e17a65f72a5133bdbec9ecf22401c62bcf4821361ef7811faee695799779"}, + {file = "contourpy-1.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1ec4dc6bf570f5b22ed0d7efba0dfa9c5b9e0431aeea7581aa217542d9e809a4"}, + {file = "contourpy-1.3.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:00ccd0dbaad6d804ab259820fa7cb0b8036bda0686ef844d24125d8287178ce0"}, + {file = "contourpy-1.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ca947601224119117f7c19c9cdf6b3ab54c5726ef1d906aa4a69dfb6dd58102"}, + {file = "contourpy-1.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c6ec93afeb848a0845a18989da3beca3eec2c0f852322efe21af1931147d12cb"}, + {file = "contourpy-1.3.0.tar.gz", hash = "sha256:7ffa0db17717a8ffb127efd0c95a4362d996b892c2904db72428d5b52e1938a4"}, ] [package.dependencies] -numpy = {version = ">=1.16,<2.0", markers = "python_version <= \"3.11\""} +numpy = ">=1.23" [package.extras] bokeh = ["bokeh", "selenium"] docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] -mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.4.1)", "types-Pillow"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.11.1)", "types-Pillow"] test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] -test-no-images = ["pytest", "pytest-cov", "wurlitzer"] +test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] [[package]] name = "contourpy" @@ -882,8 +697,8 @@ version = "1.3.3" description = "Python library for calculating contours of 2D quadrilateral grids" optional = false python-versions = ">=3.11" -groups = ["examples"] -markers = "python_version >= \"3.12\"" +groups = ["main", "examples"] +markers = "python_version >= \"3.11\"" 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"}, @@ -975,7 +790,7 @@ version = "0.12.1" description = "Composable style cycles" optional = false python-versions = ">=3.8" -groups = ["examples"] +groups = ["main", "examples"] files = [ {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, @@ -1049,6 +864,22 @@ files = [ {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, ] +[[package]] +name = "dill" +version = "0.4.0" +description = "serialize all of Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049"}, + {file = "dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0"}, +] + +[package.extras] +graph = ["objgraph (>=1.7.2)"] +profile = ["gprof2dot (>=2022.7.29)"] + [[package]] name = "exceptiongroup" version = "1.3.0" @@ -1099,79 +930,32 @@ files = [ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] [[package]] -name = "fonttools" -version = "4.57.0" -description = "Tools to manipulate font files" +name = "floris" +version = "4.5.1" +description = "A controls-oriented engineering wake model." optional = false -python-versions = ">=3.8" -groups = ["examples"] -markers = "python_version <= \"3.11\"" +python-versions = ">=3.9" +groups = ["main"] files = [ - {file = "fonttools-4.57.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:babe8d1eb059a53e560e7bf29f8e8f4accc8b6cfb9b5fd10e485bde77e71ef41"}, - {file = "fonttools-4.57.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:81aa97669cd726349eb7bd43ca540cf418b279ee3caba5e2e295fb4e8f841c02"}, - {file = "fonttools-4.57.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0e9618630edd1910ad4f07f60d77c184b2f572c8ee43305ea3265675cbbfe7e"}, - {file = "fonttools-4.57.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34687a5d21f1d688d7d8d416cb4c5b9c87fca8a1797ec0d74b9fdebfa55c09ab"}, - {file = "fonttools-4.57.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:69ab81b66ebaa8d430ba56c7a5f9abe0183afefd3a2d6e483060343398b13fb1"}, - {file = "fonttools-4.57.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d639397de852f2ccfb3134b152c741406752640a266d9c1365b0f23d7b88077f"}, - {file = "fonttools-4.57.0-cp310-cp310-win32.whl", hash = "sha256:cc066cb98b912f525ae901a24cd381a656f024f76203bc85f78fcc9e66ae5aec"}, - {file = "fonttools-4.57.0-cp310-cp310-win_amd64.whl", hash = "sha256:7a64edd3ff6a7f711a15bd70b4458611fb240176ec11ad8845ccbab4fe6745db"}, - {file = "fonttools-4.57.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3871349303bdec958360eedb619169a779956503ffb4543bb3e6211e09b647c4"}, - {file = "fonttools-4.57.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c59375e85126b15a90fcba3443eaac58f3073ba091f02410eaa286da9ad80ed8"}, - {file = "fonttools-4.57.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:967b65232e104f4b0f6370a62eb33089e00024f2ce143aecbf9755649421c683"}, - {file = "fonttools-4.57.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39acf68abdfc74e19de7485f8f7396fa4d2418efea239b7061d6ed6a2510c746"}, - {file = "fonttools-4.57.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9d077f909f2343daf4495ba22bb0e23b62886e8ec7c109ee8234bdbd678cf344"}, - {file = "fonttools-4.57.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:46370ac47a1e91895d40e9ad48effbe8e9d9db1a4b80888095bc00e7beaa042f"}, - {file = "fonttools-4.57.0-cp311-cp311-win32.whl", hash = "sha256:ca2aed95855506b7ae94e8f1f6217b7673c929e4f4f1217bcaa236253055cb36"}, - {file = "fonttools-4.57.0-cp311-cp311-win_amd64.whl", hash = "sha256:17168a4670bbe3775f3f3f72d23ee786bd965395381dfbb70111e25e81505b9d"}, - {file = "fonttools-4.57.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:889e45e976c74abc7256d3064aa7c1295aa283c6bb19810b9f8b604dfe5c7f31"}, - {file = "fonttools-4.57.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0425c2e052a5f1516c94e5855dbda706ae5a768631e9fcc34e57d074d1b65b92"}, - {file = "fonttools-4.57.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44c26a311be2ac130f40a96769264809d3b0cb297518669db437d1cc82974888"}, - {file = "fonttools-4.57.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84c41ba992df5b8d680b89fd84c6a1f2aca2b9f1ae8a67400c8930cd4ea115f6"}, - {file = "fonttools-4.57.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ea1e9e43ca56b0c12440a7c689b1350066595bebcaa83baad05b8b2675129d98"}, - {file = "fonttools-4.57.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:84fd56c78d431606332a0627c16e2a63d243d0d8b05521257d77c6529abe14d8"}, - {file = "fonttools-4.57.0-cp312-cp312-win32.whl", hash = "sha256:f4376819c1c778d59e0a31db5dc6ede854e9edf28bbfa5b756604727f7f800ac"}, - {file = "fonttools-4.57.0-cp312-cp312-win_amd64.whl", hash = "sha256:57e30241524879ea10cdf79c737037221f77cc126a8cdc8ff2c94d4a522504b9"}, - {file = "fonttools-4.57.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:408ce299696012d503b714778d89aa476f032414ae57e57b42e4b92363e0b8ef"}, - {file = "fonttools-4.57.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bbceffc80aa02d9e8b99f2a7491ed8c4a783b2fc4020119dc405ca14fb5c758c"}, - {file = "fonttools-4.57.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f022601f3ee9e1f6658ed6d184ce27fa5216cee5b82d279e0f0bde5deebece72"}, - {file = "fonttools-4.57.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dea5893b58d4637ffa925536462ba626f8a1b9ffbe2f5c272cdf2c6ebadb817"}, - {file = "fonttools-4.57.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dff02c5c8423a657c550b48231d0a48d7e2b2e131088e55983cfe74ccc2c7cc9"}, - {file = "fonttools-4.57.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:767604f244dc17c68d3e2dbf98e038d11a18abc078f2d0f84b6c24571d9c0b13"}, - {file = "fonttools-4.57.0-cp313-cp313-win32.whl", hash = "sha256:8e2e12d0d862f43d51e5afb8b9751c77e6bec7d2dc00aad80641364e9df5b199"}, - {file = "fonttools-4.57.0-cp313-cp313-win_amd64.whl", hash = "sha256:f1d6bc9c23356908db712d282acb3eebd4ae5ec6d8b696aa40342b1d84f8e9e3"}, - {file = "fonttools-4.57.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9d57b4e23ebbe985125d3f0cabbf286efa191ab60bbadb9326091050d88e8213"}, - {file = "fonttools-4.57.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:579ba873d7f2a96f78b2e11028f7472146ae181cae0e4d814a37a09e93d5c5cc"}, - {file = "fonttools-4.57.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e3e1ec10c29bae0ea826b61f265ec5c858c5ba2ce2e69a71a62f285cf8e4595"}, - {file = "fonttools-4.57.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1968f2a2003c97c4ce6308dc2498d5fd4364ad309900930aa5a503c9851aec8"}, - {file = "fonttools-4.57.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:aff40f8ac6763d05c2c8f6d240c6dac4bb92640a86d9b0c3f3fff4404f34095c"}, - {file = "fonttools-4.57.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:d07f1b64008e39fceae7aa99e38df8385d7d24a474a8c9872645c4397b674481"}, - {file = "fonttools-4.57.0-cp38-cp38-win32.whl", hash = "sha256:51d8482e96b28fb28aa8e50b5706f3cee06de85cbe2dce80dbd1917ae22ec5a6"}, - {file = "fonttools-4.57.0-cp38-cp38-win_amd64.whl", hash = "sha256:03290e818782e7edb159474144fca11e36a8ed6663d1fcbd5268eb550594fd8e"}, - {file = "fonttools-4.57.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7339e6a3283e4b0ade99cade51e97cde3d54cd6d1c3744459e886b66d630c8b3"}, - {file = "fonttools-4.57.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:05efceb2cb5f6ec92a4180fcb7a64aa8d3385fd49cfbbe459350229d1974f0b1"}, - {file = "fonttools-4.57.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a97bb05eb24637714a04dee85bdf0ad1941df64fe3b802ee4ac1c284a5f97b7c"}, - {file = "fonttools-4.57.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:541cb48191a19ceb1a2a4b90c1fcebd22a1ff7491010d3cf840dd3a68aebd654"}, - {file = "fonttools-4.57.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:cdef9a056c222d0479a1fdb721430f9efd68268014c54e8166133d2643cb05d9"}, - {file = "fonttools-4.57.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3cf97236b192a50a4bf200dc5ba405aa78d4f537a2c6e4c624bb60466d5b03bd"}, - {file = "fonttools-4.57.0-cp39-cp39-win32.whl", hash = "sha256:e952c684274a7714b3160f57ec1d78309f955c6335c04433f07d36c5eb27b1f9"}, - {file = "fonttools-4.57.0-cp39-cp39-win_amd64.whl", hash = "sha256:a2a722c0e4bfd9966a11ff55c895c817158fcce1b2b6700205a376403b546ad9"}, - {file = "fonttools-4.57.0-py3-none-any.whl", hash = "sha256:3122c604a675513c68bd24c6a8f9091f1c2376d18e8f5fe5a101746c81b3e98f"}, - {file = "fonttools-4.57.0.tar.gz", hash = "sha256:727ece10e065be2f9dd239d15dd5d60a66e17eac11aea47d447f9f03fdbc42de"}, + {file = "floris-4.5.1-py3-none-any.whl", hash = "sha256:85dd2669319c3f4987a8231862eb2cb219c6738c9c042135f734d95b593d6961"}, + {file = "floris-4.5.1.tar.gz", hash = "sha256:7823f1a0d1d286fe2e6347972aaaef70d219b95e1c01e579e1bfadfd14a12504"}, ] +[package.dependencies] +attrs = "*" +coloredlogs = ">=15.0,<16.0" +matplotlib = ">=3.0,<4.0" +numexpr = ">=2.0,<3.0" +numpy = ">=2.0,<3.0" +pandas = ">=2.0,<3.0" +pathos = ">=0.3,<1.0" +pyyaml = ">=6.0,<7.0" +scipy = ">=1.1,<2.0" +shapely = ">=2.0,<3.0" + [package.extras] -all = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "fs (>=2.2.0,<3)", "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.23.0)", "unicodedata2 (>=15.1.0) ; python_version <= \"3.12\"", "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.23.0)"] -symfont = ["sympy"] -type1 = ["xattr ; sys_platform == \"darwin\""] -ufo = ["fs (>=2.2.0,<3)"] -unicode = ["unicodedata2 (>=15.1.0) ; python_version <= \"3.12\""] -woff = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "zopfli (>=0.1.4)"] +develop = ["isort (>=5.0,<6.0)", "pre-commit (>=4.0,<5.0)", "pytest (>=8.0,<9.0)", "pytest-benchmark (>=5.1,<6.0)", "ruff (>=0.9,<1.0)"] +docs = ["bokeh (>=3.7,<4.0)", "jupyter-book (>=1.0,<2.0)", "sphinx-autodoc-typehints (>=2.0,<3.0)", "sphinx-book-theme (>=1.0,<2.0)", "sphinxcontrib-autoyaml (>=1.0,<2.0)", "sphinxcontrib.mermaid (>=1.0,<2.0)"] [[package]] name = "fonttools" @@ -1179,8 +963,7 @@ version = "4.60.1" description = "Tools to manipulate font files" optional = false python-versions = ">=3.9" -groups = ["examples"] -markers = "python_version >= \"3.12\"" +groups = ["main", "examples"] files = [ {file = "fonttools-4.60.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9a52f254ce051e196b8fe2af4634c2d2f02c981756c6464dc192f1b6050b4e28"}, {file = "fonttools-4.60.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7420a2696a44650120cdd269a5d2e56a477e2bfa9d95e86229059beb1c19e15"}, @@ -1341,6 +1124,21 @@ http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] zstd = ["zstandard (>=0.18.0)"] +[[package]] +name = "humanfriendly" +version = "10.0" +description = "Human friendly output for text interfaces using Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +groups = ["main"] +files = [ + {file = "humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477"}, + {file = "humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc"}, +] + +[package.dependencies] +pyreadline3 = {version = "*", markers = "sys_platform == \"win32\" and python_version >= \"3.8\""} + [[package]] name = "idna" version = "3.11" @@ -1363,7 +1161,7 @@ description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "python_version < \"3.10\"" +markers = "python_version == \"3.9\"" files = [ {file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"}, {file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"}, @@ -1387,12 +1185,12 @@ version = "6.4.5" description = "Read resources from Python packages" optional = false python-versions = ">=3.8" -groups = ["dev", "examples"] +groups = ["main", "examples"] +markers = "python_version == \"3.9\"" files = [ {file = "importlib_resources-6.4.5-py3-none-any.whl", hash = "sha256:ac29d5f956f01d5e4bb63102a5a19957f1b9175e45649977264a1416783bb717"}, {file = "importlib_resources-6.4.5.tar.gz", hash = "sha256:980862a1d16c9e147a59603677fa2aa5fd82b87f223b6cb870695bcfce830065"}, ] -markers = {dev = "python_version == \"3.8\"", examples = "python_version < \"3.10\""} [package.dependencies] zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} @@ -1412,7 +1210,7 @@ description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "python_version <= \"3.11\"" +markers = "python_version < \"3.11\"" files = [ {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, @@ -1425,47 +1223,12 @@ description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.10" groups = ["dev"] -markers = "python_version >= \"3.12\"" +markers = "python_version >= \"3.11\"" 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 = "6.29.5" -description = "IPython Kernel for Jupyter" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5"}, - {file = "ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215"}, -] - -[package.dependencies] -appnope = {version = "*", markers = "platform_system == \"Darwin\""} -comm = ">=0.1.1" -debugpy = ">=1.6.5" -ipython = ">=7.23.1" -jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -matplotlib-inline = ">=0.1" -nest-asyncio = "*" -packaging = "*" -psutil = "*" -pyzmq = ">=24" -tornado = ">=6.1" -traitlets = ">=5.4.0" - -[package.extras] -cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] -pyqt5 = ["pyqt5"] -pyside6 = ["pyside6"] -test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.23.5)", "pytest-cov", "pytest-timeout"] - [[package]] name = "ipykernel" version = "6.31.0" @@ -1473,7 +1236,6 @@ description = "IPython Kernel for Jupyter" optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "ipykernel-6.31.0-py3-none-any.whl", hash = "sha256:abe5386f6ced727a70e0eb0cf1da801fa7c5fa6ff82147747d5a0406cd8c94af"}, {file = "ipykernel-6.31.0.tar.gz", hash = "sha256:2372ce8bc1ff4f34e58cafed3a0feb2194b91fc7cad0fc72e79e47b45ee9e8f6"}, @@ -1508,7 +1270,7 @@ description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "python_version <= \"3.11\"" +markers = "python_version < \"3.11\"" files = [ {file = "ipython-8.12.3-py3-none-any.whl", hash = "sha256:b0340d46a933d27c657b211a329d0be23793c36595acf9e6ef4164bc01a1804c"}, {file = "ipython-8.12.3.tar.gz", hash = "sha256:3910c4b54543c2ad73d06579aa771041b7d5707b033bd488669b4cf544e3b363"}, @@ -1549,7 +1311,7 @@ description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.10" groups = ["dev"] -markers = "python_version >= \"3.12\"" +markers = "python_version >= \"3.11\"" files = [ {file = "ipython-8.37.0-py3-none-any.whl", hash = "sha256:ed87326596b878932dbcb171e3e698845434d8c61b8d8cd474bf663041a9dcf2"}, {file = "ipython-8.37.0.tar.gz", hash = "sha256:ca815841e1a41a1e6b73a0b08f3038af9b2252564d01fc405356d34033012216"}, @@ -1565,6 +1327,7 @@ prompt_toolkit = ">=3.0.41,<3.1.0" pygments = ">=2.4.0" stack_data = "*" traitlets = ">=5.13.0" +typing_extensions = {version = ">=4.6", markers = "python_version < \"3.12\""} [package.extras] all = ["ipython[black,doc,kernel,matplotlib,nbconvert,nbformat,notebook,parallel,qtconsole]", "ipython[test,test-extra]"] @@ -1682,39 +1445,6 @@ files = [ {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, ] -[[package]] -name = "jsonschema" -version = "4.23.0" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, - {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, -] - -[package.dependencies] -attrs = ">=22.2.0" -fqdn = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -idna = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} -isoduration = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -jsonpointer = {version = ">1.13", optional = true, markers = "extra == \"format-nongpl\""} -jsonschema-specifications = ">=2023.03.6" -pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} -referencing = ">=0.28.4" -rfc3339-validator = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format-nongpl\""} -rpds-py = ">=0.7.1" -uri-template = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -webcolors = {version = ">=24.6.0", optional = true, markers = "extra == \"format-nongpl\""} - -[package.extras] -format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] - [[package]] name = "jsonschema" version = "4.25.1" @@ -1722,7 +1452,6 @@ description = "An implementation of JSON Schema validation for Python" optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "jsonschema-4.25.1-py3-none-any.whl", hash = "sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63"}, {file = "jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85"}, @@ -1747,23 +1476,6 @@ webcolors = {version = ">=24.6.0", optional = true, markers = "extra == \"format 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 = "2023.12.1" -description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, - {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, -] - -[package.dependencies] -importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} -referencing = ">=0.31.0" - [[package]] name = "jsonschema-specifications" version = "2025.9.1" @@ -1771,7 +1483,6 @@ description = "The JSON Schema meta-schemas and vocabularies, exposed as a Regis optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" 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"}, @@ -1856,7 +1567,7 @@ description = "Jupyter core package. A base package on which Jupyter projects re optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "python_version <= \"3.11\"" +markers = "python_version < \"3.11\"" files = [ {file = "jupyter_core-5.8.1-py3-none-any.whl", hash = "sha256:c28d268fc90fb53f1338ded2eb410704c5449a358406e8a948b75706e24863d0"}, {file = "jupyter_core-5.8.1.tar.gz", hash = "sha256:0a5f9706f70e64786b75acba995988915ebd4601c8a52e534a40b51c95f59941"}, @@ -1878,7 +1589,7 @@ description = "Jupyter core package. A base package on which Jupyter projects re optional = false python-versions = ">=3.10" groups = ["dev"] -markers = "python_version >= \"3.12\"" +markers = "python_version >= \"3.11\"" 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"}, @@ -1892,33 +1603,6 @@ traitlets = ">=5.3" 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 = "jupyter-events" -version = "0.10.0" -description = "Jupyter Event System library" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "jupyter_events-0.10.0-py3-none-any.whl", hash = "sha256:4b72130875e59d57716d327ea70d3ebc3af1944d3717e5a498b8a06c6c159960"}, - {file = "jupyter_events-0.10.0.tar.gz", hash = "sha256:670b8229d3cc882ec782144ed22e0d29e1c2d639263f92ca8383e66682845e22"}, -] - -[package.dependencies] -jsonschema = {version = ">=4.18.0", extras = ["format-nongpl"]} -python-json-logger = ">=2.0.4" -pyyaml = ">=5.3" -referencing = "*" -rfc3339-validator = "*" -rfc3986-validator = ">=0.1.1" -traitlets = ">=5.3" - -[package.extras] -cli = ["click", "rich"] -docs = ["jupyterlite-sphinx", "myst-parser", "pydata-sphinx-theme", "sphinxcontrib-spelling"] -test = ["click", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "pytest-console-scripts", "rich"] - [[package]] name = "jupyter-events" version = "0.12.0" @@ -1926,7 +1610,6 @@ description = "Jupyter Event System library" optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "jupyter_events-0.12.0-py3-none-any.whl", hash = "sha256:6464b2fa5ad10451c3d35fabc75eab39556ae1e2853ad0c0cc31b656731a97fb"}, {file = "jupyter_events-0.12.0.tar.gz", hash = "sha256:fc3fce98865f6784c9cd0a56a20644fc6098f21c8c33834a8d9fe383c17e554b"}, @@ -1963,44 +1646,6 @@ files = [ importlib_metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} jupyter_server = ">=1.1.2" -[[package]] -name = "jupyter-server" -version = "2.14.2" -description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "jupyter_server-2.14.2-py3-none-any.whl", hash = "sha256:47ff506127c2f7851a17bf4713434208fc490955d0e8632e95014a9a9afbeefd"}, - {file = "jupyter_server-2.14.2.tar.gz", hash = "sha256:66095021aa9638ced276c248b1d81862e4c50f292d575920bbe960de1c56b12b"}, -] - -[package.dependencies] -anyio = ">=3.1.0" -argon2-cffi = ">=21.1" -jinja2 = ">=3.0.3" -jupyter-client = ">=7.4.4" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -jupyter-events = ">=0.9.0" -jupyter-server-terminals = ">=0.4.4" -nbconvert = ">=6.4.4" -nbformat = ">=5.3.0" -overrides = ">=5.0" -packaging = ">=22.0" -prometheus-client = ">=0.9" -pywinpty = {version = ">=2.0.1", markers = "os_name == \"nt\""} -pyzmq = ">=24" -send2trash = ">=1.8.2" -terminado = ">=0.8.3" -tornado = ">=6.2.0" -traitlets = ">=5.6.0" -websocket-client = ">=1.7" - -[package.extras] -docs = ["ipykernel", "jinja2", "jupyter-client", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi (>=0.8.0)", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] -test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0,<9)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.7)", "pytest-timeout", "requests"] - [[package]] name = "jupyter-server" version = "2.17.0" @@ -2008,7 +1653,6 @@ description = "The backend—i.e. core services, APIs, and REST endpoints—to J optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "jupyter_server-2.17.0-py3-none-any.whl", hash = "sha256:e8cb9c7db4251f51ed307e329b81b72ccf2056ff82d50524debde1ee1870e13f"}, {file = "jupyter_server-2.17.0.tar.gz", hash = "sha256:c38ea898566964c888b4772ae1ed58eca84592e88251d2cfc4d171f81f7e99d5"}, @@ -2024,6 +1668,7 @@ jupyter-events = ">=0.11.0" jupyter-server-terminals = ">=0.4.4" nbconvert = ">=6.4.4" nbformat = ">=5.3.0" +overrides = {version = ">=5.0", markers = "python_version < \"3.12\""} packaging = ">=22.0" prometheus-client = ">=0.9" pywinpty = {version = ">=2.0.1", markers = "os_name == \"nt\""} @@ -2058,44 +1703,6 @@ terminado = ">=0.8.3" docs = ["jinja2", "jupyter-server", "mistune (<4.0)", "myst-parser", "nbformat", "packaging", "pydata-sphinx-theme", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado"] test = ["jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-jupyter[server] (>=0.5.3)", "pytest-timeout"] -[[package]] -name = "jupyterlab" -version = "4.3.8" -description = "JupyterLab computational environment" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "jupyterlab-4.3.8-py3-none-any.whl", hash = "sha256:8c6451ef224a18b457975fd52010e45a7aef58b719dfb242c5f253e0e48ea047"}, - {file = "jupyterlab-4.3.8.tar.gz", hash = "sha256:2ffd0e7b82786dba54743f4d1646130642ed81cb9e52f0a31e79416f6e5ba2e7"}, -] - -[package.dependencies] -async-lru = ">=1.0.0" -httpx = ">=0.25.0" -importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} -importlib-resources = {version = ">=1.4", markers = "python_version < \"3.9\""} -ipykernel = ">=6.5.0" -jinja2 = ">=3.0.3" -jupyter-core = "*" -jupyter-lsp = ">=2.0.0" -jupyter-server = ">=2.4.0,<3" -jupyterlab-server = ">=2.27.1,<3" -notebook-shim = ">=0.2" -packaging = "*" -setuptools = ">=41.1.0" -tomli = {version = ">=1.2.2", markers = "python_version < \"3.11\""} -tornado = ">=6.2.0" -traitlets = "*" - -[package.extras] -dev = ["build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", "ruff (==0.6.9)"] -docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-jupyter", "sphinx (>=1.8,<8.1.0)", "sphinx-copybutton"] -docs-screenshots = ["altair (==5.5.0)", "ipython (==8.16.1)", "ipywidgets (==8.1.5)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.2.post3)", "matplotlib (==3.9.2)", "nbconvert (>=7.0.0)", "pandas (==2.2.3)", "scipy (==1.14.1)", "vega-datasets (==0.9.0)"] -test = ["coverage", "pytest (>=7.0)", "pytest-check-links (>=0.7)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter (>=0.5.3)", "pytest-timeout", "pytest-tornasync", "requests", "requests-cache", "virtualenv"] -upgrade-extension = ["copier (>=9,<10)", "jinja2-time (<0.3)", "pydantic (<3.0)", "pyyaml-include (<3.0)", "tomli-w (<2.0)"] - [[package]] name = "jupyterlab" version = "4.4.10" @@ -2103,7 +1710,6 @@ description = "JupyterLab computational environment" optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "jupyterlab-4.4.10-py3-none-any.whl", hash = "sha256:65939ab4c8dcd0c42185c2d0d1a9d60b254dc8c46fc4fdb286b63c51e9358e07"}, {file = "jupyterlab-4.4.10.tar.gz", hash = "sha256:521c017508af4e1d6d9d8a9d90f47a11c61197ad63b2178342489de42540a615"}, @@ -2112,6 +1718,7 @@ files = [ [package.dependencies] async-lru = ">=1.0.0" httpx = ">=0.25.0,<1" +importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} ipykernel = ">=6.5.0,<6.30.0 || >6.30.0" jinja2 = ">=3.0.3" jupyter-core = "*" @@ -2121,6 +1728,7 @@ jupyterlab-server = ">=2.27.1,<3" notebook-shim = ">=0.2" packaging = "*" setuptools = ">=41.1.0" +tomli = {version = ">=1.2.2", markers = "python_version < \"3.11\""} tornado = ">=6.2.0" traitlets = "*" @@ -2188,8 +1796,8 @@ version = "1.4.7" description = "A fast implementation of the Cassowary constraint solver" optional = false python-versions = ">=3.8" -groups = ["examples"] -markers = "python_version <= \"3.11\"" +groups = ["main", "examples"] +markers = "python_version < \"3.11\"" files = [ {file = "kiwisolver-1.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8a9c83f75223d5e48b0bc9cb1bf2776cf01563e00ade8775ffe13b0b6e1af3a6"}, {file = "kiwisolver-1.4.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:58370b1ffbd35407444d57057b57da5d6549d2d854fa30249771775c63b5fe17"}, @@ -2313,8 +1921,8 @@ version = "1.4.9" description = "A fast implementation of the Cassowary constraint solver" optional = false python-versions = ">=3.10" -groups = ["examples"] -markers = "python_version >= \"3.12\"" +groups = ["main", "examples"] +markers = "python_version >= \"3.11\"" 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"}, @@ -2426,7 +2034,6 @@ description = "a modern parsing library" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "lark-1.3.1-py3-none-any.whl", hash = "sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12"}, {file = "lark-1.3.1.tar.gz", hash = "sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905"}, @@ -2438,77 +2045,6 @@ interegular = ["interegular (>=0.3.1,<0.4.0)"] nearley = ["js2py"] regex = ["regex"] -[[package]] -name = "markupsafe" -version = "2.1.5" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.7" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, -] - [[package]] name = "markupsafe" version = "3.0.3" @@ -2516,7 +2052,6 @@ description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" 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"}, @@ -2611,60 +2146,54 @@ files = [ [[package]] name = "matplotlib" -version = "3.7.5" +version = "3.9.4" description = "Python plotting package" optional = false -python-versions = ">=3.8" -groups = ["examples"] -markers = "python_version <= \"3.11\"" +python-versions = ">=3.9" +groups = ["main", "examples"] +markers = "python_version < \"3.11\"" files = [ - {file = "matplotlib-3.7.5-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:4a87b69cb1cb20943010f63feb0b2901c17a3b435f75349fd9865713bfa63925"}, - {file = "matplotlib-3.7.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d3ce45010fefb028359accebb852ca0c21bd77ec0f281952831d235228f15810"}, - {file = "matplotlib-3.7.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fbea1e762b28400393d71be1a02144aa16692a3c4c676ba0178ce83fc2928fdd"}, - {file = "matplotlib-3.7.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec0e1adc0ad70ba8227e957551e25a9d2995e319c29f94a97575bb90fa1d4469"}, - {file = "matplotlib-3.7.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6738c89a635ced486c8a20e20111d33f6398a9cbebce1ced59c211e12cd61455"}, - {file = "matplotlib-3.7.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1210b7919b4ed94b5573870f316bca26de3e3b07ffdb563e79327dc0e6bba515"}, - {file = "matplotlib-3.7.5-cp310-cp310-win32.whl", hash = "sha256:068ebcc59c072781d9dcdb82f0d3f1458271c2de7ca9c78f5bd672141091e9e1"}, - {file = "matplotlib-3.7.5-cp310-cp310-win_amd64.whl", hash = "sha256:f098ffbaab9df1e3ef04e5a5586a1e6b1791380698e84938d8640961c79b1fc0"}, - {file = "matplotlib-3.7.5-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:f65342c147572673f02a4abec2d5a23ad9c3898167df9b47c149f32ce61ca078"}, - {file = "matplotlib-3.7.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4ddf7fc0e0dc553891a117aa083039088d8a07686d4c93fb8a810adca68810af"}, - {file = "matplotlib-3.7.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0ccb830fc29442360d91be48527809f23a5dcaee8da5f4d9b2d5b867c1b087b8"}, - {file = "matplotlib-3.7.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efc6bb28178e844d1f408dd4d6341ee8a2e906fc9e0fa3dae497da4e0cab775d"}, - {file = "matplotlib-3.7.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b15c4c2d374f249f324f46e883340d494c01768dd5287f8bc00b65b625ab56c"}, - {file = "matplotlib-3.7.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d028555421912307845e59e3de328260b26d055c5dac9b182cc9783854e98fb"}, - {file = "matplotlib-3.7.5-cp311-cp311-win32.whl", hash = "sha256:fe184b4625b4052fa88ef350b815559dd90cc6cc8e97b62f966e1ca84074aafa"}, - {file = "matplotlib-3.7.5-cp311-cp311-win_amd64.whl", hash = "sha256:084f1f0f2f1010868c6f1f50b4e1c6f2fb201c58475494f1e5b66fed66093647"}, - {file = "matplotlib-3.7.5-cp312-cp312-macosx_10_12_universal2.whl", hash = "sha256:34bceb9d8ddb142055ff27cd7135f539f2f01be2ce0bafbace4117abe58f8fe4"}, - {file = "matplotlib-3.7.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c5a2134162273eb8cdfd320ae907bf84d171de948e62180fa372a3ca7cf0f433"}, - {file = "matplotlib-3.7.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:039ad54683a814002ff37bf7981aa1faa40b91f4ff84149beb53d1eb64617980"}, - {file = "matplotlib-3.7.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d742ccd1b09e863b4ca58291728db645b51dab343eebb08d5d4b31b308296ce"}, - {file = "matplotlib-3.7.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:743b1c488ca6a2bc7f56079d282e44d236bf375968bfd1b7ba701fd4d0fa32d6"}, - {file = "matplotlib-3.7.5-cp312-cp312-win_amd64.whl", hash = "sha256:fbf730fca3e1f23713bc1fae0a57db386e39dc81ea57dc305c67f628c1d7a342"}, - {file = "matplotlib-3.7.5-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:cfff9b838531698ee40e40ea1a8a9dc2c01edb400b27d38de6ba44c1f9a8e3d2"}, - {file = "matplotlib-3.7.5-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:1dbcca4508bca7847fe2d64a05b237a3dcaec1f959aedb756d5b1c67b770c5ee"}, - {file = "matplotlib-3.7.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4cdf4ef46c2a1609a50411b66940b31778db1e4b73d4ecc2eaa40bd588979b13"}, - {file = "matplotlib-3.7.5-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:167200ccfefd1674b60e957186dfd9baf58b324562ad1a28e5d0a6b3bea77905"}, - {file = "matplotlib-3.7.5-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:53e64522934df6e1818b25fd48cf3b645b11740d78e6ef765fbb5fa5ce080d02"}, - {file = "matplotlib-3.7.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3e3bc79b2d7d615067bd010caff9243ead1fc95cf735c16e4b2583173f717eb"}, - {file = "matplotlib-3.7.5-cp38-cp38-win32.whl", hash = "sha256:6b641b48c6819726ed47c55835cdd330e53747d4efff574109fd79b2d8a13748"}, - {file = "matplotlib-3.7.5-cp38-cp38-win_amd64.whl", hash = "sha256:f0b60993ed3488b4532ec6b697059897891927cbfc2b8d458a891b60ec03d9d7"}, - {file = "matplotlib-3.7.5-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:090964d0afaff9c90e4d8de7836757e72ecfb252fb02884016d809239f715651"}, - {file = "matplotlib-3.7.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:9fc6fcfbc55cd719bc0bfa60bde248eb68cf43876d4c22864603bdd23962ba25"}, - {file = "matplotlib-3.7.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7cc3078b019bb863752b8b60e8b269423000f1603cb2299608231996bd9d54"}, - {file = "matplotlib-3.7.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e4e9a868e8163abaaa8259842d85f949a919e1ead17644fb77a60427c90473c"}, - {file = "matplotlib-3.7.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa7ebc995a7d747dacf0a717d0eb3aa0f0c6a0e9ea88b0194d3a3cd241a1500f"}, - {file = "matplotlib-3.7.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3785bfd83b05fc0e0c2ae4c4a90034fe693ef96c679634756c50fe6efcc09856"}, - {file = "matplotlib-3.7.5-cp39-cp39-win32.whl", hash = "sha256:29b058738c104d0ca8806395f1c9089dfe4d4f0f78ea765c6c704469f3fffc81"}, - {file = "matplotlib-3.7.5-cp39-cp39-win_amd64.whl", hash = "sha256:fd4028d570fa4b31b7b165d4a685942ae9cdc669f33741e388c01857d9723eab"}, - {file = "matplotlib-3.7.5-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2a9a3f4d6a7f88a62a6a18c7e6a84aedcaf4faf0708b4ca46d87b19f1b526f88"}, - {file = "matplotlib-3.7.5-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b9b3fd853d4a7f008a938df909b96db0b454225f935d3917520305b90680579c"}, - {file = "matplotlib-3.7.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0ad550da9f160737d7890217c5eeed4337d07e83ca1b2ca6535078f354e7675"}, - {file = "matplotlib-3.7.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:20da7924a08306a861b3f2d1da0d1aa9a6678e480cf8eacffe18b565af2813e7"}, - {file = "matplotlib-3.7.5-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b45c9798ea6bb920cb77eb7306409756a7fab9db9b463e462618e0559aecb30e"}, - {file = "matplotlib-3.7.5-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a99866267da1e561c7776fe12bf4442174b79aac1a47bd7e627c7e4d077ebd83"}, - {file = "matplotlib-3.7.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b6aa62adb6c268fc87d80f963aca39c64615c31830b02697743c95590ce3fbb"}, - {file = "matplotlib-3.7.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e530ab6a0afd082d2e9c17eb1eb064a63c5b09bb607b2b74fa41adbe3e162286"}, - {file = "matplotlib-3.7.5.tar.gz", hash = "sha256:1e5c971558ebc811aa07f54c7b7c677d78aa518ef4c390e14673a09e0860184a"}, + {file = "matplotlib-3.9.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:c5fdd7abfb706dfa8d307af64a87f1a862879ec3cd8d0ec8637458f0885b9c50"}, + {file = "matplotlib-3.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d89bc4e85e40a71d1477780366c27fb7c6494d293e1617788986f74e2a03d7ff"}, + {file = "matplotlib-3.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddf9f3c26aae695c5daafbf6b94e4c1a30d6cd617ba594bbbded3b33a1fcfa26"}, + {file = "matplotlib-3.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18ebcf248030173b59a868fda1fe42397253f6698995b55e81e1f57431d85e50"}, + {file = "matplotlib-3.9.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:974896ec43c672ec23f3f8c648981e8bc880ee163146e0312a9b8def2fac66f5"}, + {file = "matplotlib-3.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:4598c394ae9711cec135639374e70871fa36b56afae17bdf032a345be552a88d"}, + {file = "matplotlib-3.9.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d4dd29641d9fb8bc4492420c5480398dd40a09afd73aebe4eb9d0071a05fbe0c"}, + {file = "matplotlib-3.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30e5b22e8bcfb95442bf7d48b0d7f3bdf4a450cbf68986ea45fca3d11ae9d099"}, + {file = "matplotlib-3.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bb0030d1d447fd56dcc23b4c64a26e44e898f0416276cac1ebc25522e0ac249"}, + {file = "matplotlib-3.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aca90ed222ac3565d2752b83dbb27627480d27662671e4d39da72e97f657a423"}, + {file = "matplotlib-3.9.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a181b2aa2906c608fcae72f977a4a2d76e385578939891b91c2550c39ecf361e"}, + {file = "matplotlib-3.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:1f6882828231eca17f501c4dcd98a05abb3f03d157fbc0769c6911fe08b6cfd3"}, + {file = "matplotlib-3.9.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:dfc48d67e6661378a21c2983200a654b72b5c5cdbd5d2cf6e5e1ece860f0cc70"}, + {file = "matplotlib-3.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:47aef0fab8332d02d68e786eba8113ffd6f862182ea2999379dec9e237b7e483"}, + {file = "matplotlib-3.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fba1f52c6b7dc764097f52fd9ab627b90db452c9feb653a59945de16752e965f"}, + {file = "matplotlib-3.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:173ac3748acaac21afcc3fa1633924609ba1b87749006bc25051c52c422a5d00"}, + {file = "matplotlib-3.9.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320edea0cadc07007765e33f878b13b3738ffa9745c5f707705692df70ffe0e0"}, + {file = "matplotlib-3.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a4a4cfc82330b27042a7169533da7991e8789d180dd5b3daeaee57d75cd5a03b"}, + {file = "matplotlib-3.9.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:37eeffeeca3c940985b80f5b9a7b95ea35671e0e7405001f249848d2b62351b6"}, + {file = "matplotlib-3.9.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3e7465ac859ee4abcb0d836137cd8414e7bb7ad330d905abced457217d4f0f45"}, + {file = "matplotlib-3.9.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4c12302c34afa0cf061bea23b331e747e5e554b0fa595c96e01c7b75bc3b858"}, + {file = "matplotlib-3.9.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b8c97917f21b75e72108b97707ba3d48f171541a74aa2a56df7a40626bafc64"}, + {file = "matplotlib-3.9.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0229803bd7e19271b03cb09f27db76c918c467aa4ce2ae168171bc67c3f508df"}, + {file = "matplotlib-3.9.4-cp313-cp313-win_amd64.whl", hash = "sha256:7c0d8ef442ebf56ff5e206f8083d08252ee738e04f3dc88ea882853a05488799"}, + {file = "matplotlib-3.9.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a04c3b00066a688834356d196136349cb32f5e1003c55ac419e91585168b88fb"}, + {file = "matplotlib-3.9.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:04c519587f6c210626741a1e9a68eefc05966ede24205db8982841826af5871a"}, + {file = "matplotlib-3.9.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:308afbf1a228b8b525fcd5cec17f246bbbb63b175a3ef6eb7b4d33287ca0cf0c"}, + {file = "matplotlib-3.9.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddb3b02246ddcffd3ce98e88fed5b238bc5faff10dbbaa42090ea13241d15764"}, + {file = "matplotlib-3.9.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8a75287e9cb9eee48cb79ec1d806f75b29c0fde978cb7223a1f4c5848d696041"}, + {file = "matplotlib-3.9.4-cp313-cp313t-win_amd64.whl", hash = "sha256:488deb7af140f0ba86da003e66e10d55ff915e152c78b4b66d231638400b1965"}, + {file = "matplotlib-3.9.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3c3724d89a387ddf78ff88d2a30ca78ac2b4c89cf37f2db4bd453c34799e933c"}, + {file = "matplotlib-3.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d5f0a8430ffe23d7e32cfd86445864ccad141797f7d25b7c41759a5b5d17cfd7"}, + {file = "matplotlib-3.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bb0141a21aef3b64b633dc4d16cbd5fc538b727e4958be82a0e1c92a234160e"}, + {file = "matplotlib-3.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57aa235109e9eed52e2c2949db17da185383fa71083c00c6c143a60e07e0888c"}, + {file = "matplotlib-3.9.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b18c600061477ccfdd1e6fd050c33d8be82431700f3452b297a56d9ed7037abb"}, + {file = "matplotlib-3.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:ef5f2d1b67d2d2145ff75e10f8c008bfbf71d45137c4b648c87193e7dd053eac"}, + {file = "matplotlib-3.9.4-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:44e0ed786d769d85bc787b0606a53f2d8d2d1d3c8a2608237365e9121c1a338c"}, + {file = "matplotlib-3.9.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:09debb9ce941eb23ecdbe7eab972b1c3e0276dcf01688073faff7b0f61d6c6ca"}, + {file = "matplotlib-3.9.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcc53cf157a657bfd03afab14774d54ba73aa84d42cfe2480c91bd94873952db"}, + {file = "matplotlib-3.9.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ad45da51be7ad02387801fd154ef74d942f49fe3fcd26a64c94842ba7ec0d865"}, + {file = "matplotlib-3.9.4.tar.gz", hash = "sha256:1e00e8be7393cbdc6fedfa8a6fba02cf3e83814b285db1c60b906a023ba41bc3"}, ] [package.dependencies] @@ -2672,21 +2201,24 @@ contourpy = ">=1.0.1" cycler = ">=0.10" fonttools = ">=4.22.0" importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} -kiwisolver = ">=1.0.1" -numpy = ">=1.20,<2" +kiwisolver = ">=1.3.1" +numpy = ">=1.23" packaging = ">=20.0" -pillow = ">=6.2.0" +pillow = ">=8" pyparsing = ">=2.3.1" python-dateutil = ">=2.7" +[package.extras] +dev = ["meson-python (>=0.13.1,<0.17.0)", "numpy (>=1.25)", "pybind11 (>=2.6,!=2.13.3)", "setuptools (>=64)", "setuptools_scm (>=7)"] + [[package]] name = "matplotlib" version = "3.10.7" description = "Python plotting package" optional = false python-versions = ">=3.10" -groups = ["examples"] -markers = "python_version >= \"3.12\"" +groups = ["main", "examples"] +markers = "python_version >= \"3.11\"" files = [ {file = "matplotlib-3.10.7-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7ac81eee3b7c266dd92cee1cd658407b16c57eed08c7421fa354ed68234de380"}, {file = "matplotlib-3.10.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:667ecd5d8d37813a845053d8f5bf110b534c3c9f30e69ebd25d4701385935a6d"}, @@ -2759,22 +2291,6 @@ 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.1.7" -description = "Inline Matplotlib backend for Jupyter" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, - {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, -] - -[package.dependencies] -traitlets = "*" - [[package]] name = "matplotlib-inline" version = "0.2.1" @@ -2782,7 +2298,6 @@ description = "Inline Matplotlib backend for Jupyter" optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" 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"}, @@ -2810,65 +2325,36 @@ files = [ typing-extensions = {version = "*", markers = "python_version < \"3.11\""} [[package]] -name = "mypy" -version = "1.14.1" -description = "Optional static typing for Python" +name = "multiprocess" +version = "0.70.18" +description = "better multiprocessing and multithreading in Python" optional = false python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" +groups = ["main"] files = [ - {file = "mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb"}, - {file = "mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0"}, - {file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d"}, - {file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b"}, - {file = "mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427"}, - {file = "mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f"}, - {file = "mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c"}, - {file = "mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1"}, - {file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8"}, - {file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f"}, - {file = "mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1"}, - {file = "mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae"}, - {file = "mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14"}, - {file = "mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9"}, - {file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11"}, - {file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e"}, - {file = "mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89"}, - {file = "mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b"}, - {file = "mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255"}, - {file = "mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34"}, - {file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a"}, - {file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9"}, - {file = "mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd"}, - {file = "mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107"}, - {file = "mypy-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7084fb8f1128c76cd9cf68fe5971b37072598e7c31b2f9f95586b65c741a9d31"}, - {file = "mypy-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f845a00b4f420f693f870eaee5f3e2692fa84cc8514496114649cfa8fd5e2c6"}, - {file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44bf464499f0e3a2d14d58b54674dee25c031703b2ffc35064bd0df2e0fac319"}, - {file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c99f27732c0b7dc847adb21c9d47ce57eb48fa33a17bc6d7d5c5e9f9e7ae5bac"}, - {file = "mypy-1.14.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:bce23c7377b43602baa0bd22ea3265c49b9ff0b76eb315d6c34721af4cdf1d9b"}, - {file = "mypy-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:8edc07eeade7ebc771ff9cf6b211b9a7d93687ff892150cb5692e4f4272b0837"}, - {file = "mypy-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3888a1816d69f7ab92092f785a462944b3ca16d7c470d564165fe703b0970c35"}, - {file = "mypy-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46c756a444117c43ee984bd055db99e498bc613a70bbbc120272bd13ca579fbc"}, - {file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27fc248022907e72abfd8e22ab1f10e903915ff69961174784a3900a8cba9ad9"}, - {file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:499d6a72fb7e5de92218db961f1a66d5f11783f9ae549d214617edab5d4dbdbb"}, - {file = "mypy-1.14.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57961db9795eb566dc1d1b4e9139ebc4c6b0cb6e7254ecde69d1552bf7613f60"}, - {file = "mypy-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:07ba89fdcc9451f2ebb02853deb6aaaa3d2239a236669a63ab3801bbf923ef5c"}, - {file = "mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1"}, - {file = "mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6"}, + {file = "multiprocess-0.70.18-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:25d4012dcaaf66b9e8e955f58482b42910c2ee526d532844d8bcf661bbc604df"}, + {file = "multiprocess-0.70.18-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:06b19433de0d02afe5869aec8931dd5c01d99074664f806c73896b0d9e527213"}, + {file = "multiprocess-0.70.18-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6fa1366f994373aaf2d4738b0f56e707caeaa05486e97a7f71ee0853823180c2"}, + {file = "multiprocess-0.70.18-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8b8940ae30139e04b076da6c5b83e9398585ebdf0f2ad3250673fef5b2ff06d6"}, + {file = "multiprocess-0.70.18-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0929ba95831adb938edbd5fb801ac45e705ecad9d100b3e653946b7716cb6bd3"}, + {file = "multiprocess-0.70.18-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4d77f8e4bfe6c6e2e661925bbf9aed4d5ade9a1c6502d5dfc10129b9d1141797"}, + {file = "multiprocess-0.70.18-pp38-pypy38_pp73-macosx_10_9_arm64.whl", hash = "sha256:2dbaae9bffa1fb2d58077c0044ffe87a8c8974e90fcf778cdf90e139c970d42a"}, + {file = "multiprocess-0.70.18-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bcac5a4e81f1554d98d1bba963eeb1bd24966432f04fcbd29b6e1a16251ad712"}, + {file = "multiprocess-0.70.18-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c0c7cd75d0987ab6166d64e654787c781dbacbcbcaaede4c1ffe664720b3e14b"}, + {file = "multiprocess-0.70.18-pp39-pypy39_pp73-macosx_10_13_arm64.whl", hash = "sha256:9fd8d662f7524a95a1be7cbea271f0b33089fe792baabec17d93103d368907da"}, + {file = "multiprocess-0.70.18-pp39-pypy39_pp73-macosx_10_13_x86_64.whl", hash = "sha256:3fbba48bfcd932747c33f0b152b26207c4e0840c35cab359afaff7a8672b1031"}, + {file = "multiprocess-0.70.18-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:5f9be0342e597dde86152c10442c5fb6c07994b1c29de441b7a3a08b0e6be2a0"}, + {file = "multiprocess-0.70.18-py310-none-any.whl", hash = "sha256:60c194974c31784019c1f459d984e8f33ee48f10fcf42c309ba97b30d9bd53ea"}, + {file = "multiprocess-0.70.18-py311-none-any.whl", hash = "sha256:5aa6eef98e691281b3ad923be2832bf1c55dd2c859acd73e5ec53a66aae06a1d"}, + {file = "multiprocess-0.70.18-py312-none-any.whl", hash = "sha256:9b78f8e5024b573730bfb654783a13800c2c0f2dfc0c25e70b40d184d64adaa2"}, + {file = "multiprocess-0.70.18-py313-none-any.whl", hash = "sha256:871743755f43ef57d7910a38433cfe41319e72be1bbd90b79c7a5ac523eb9334"}, + {file = "multiprocess-0.70.18-py38-none-any.whl", hash = "sha256:dbf705e52a154fe5e90fb17b38f02556169557c2dd8bb084f2e06c2784d8279b"}, + {file = "multiprocess-0.70.18-py39-none-any.whl", hash = "sha256:e78ca805a72b1b810c690b6b4cc32579eba34f403094bbbae962b7b5bf9dfcb8"}, + {file = "multiprocess-0.70.18.tar.gz", hash = "sha256:f9597128e6b3e67b23956da07cf3d2e5cba79e2f4e0fba8d7903636663ec6d0d"}, ] [package.dependencies] -mypy_extensions = ">=1.0.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing_extensions = ">=4.6.0" - -[package.extras] -dmypy = ["psutil (>=4.0)"] -faster-cache = ["orjson"] -install-types = ["pip"] -mypyc = ["setuptools (>=50)"] -reports = ["lxml"] +dill = ">=0.4.0" [[package]] name = "mypy" @@ -2877,7 +2363,6 @@ description = "Optional static typing for Python" optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "mypy-1.18.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c1eab0cf6294dafe397c261a75f96dc2c31bffe3b944faa24db5def4e2b0f77c"}, {file = "mypy-1.18.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a780ca61fc239e4865968ebc5240bb3bf610ef59ac398de9a7421b54e4a207e"}, @@ -2922,6 +2407,7 @@ files = [ [package.dependencies] mypy_extensions = ">=1.0.0" pathspec = ">=0.9.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typing_extensions = ">=4.6.0" [package.extras] @@ -2943,30 +2429,6 @@ files = [ {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, ] -[[package]] -name = "nbclient" -version = "0.10.1" -description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." -optional = false -python-versions = ">=3.8.0" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "nbclient-0.10.1-py3-none-any.whl", hash = "sha256:949019b9240d66897e442888cfb618f69ef23dc71c01cb5fced8499c2cfc084d"}, - {file = "nbclient-0.10.1.tar.gz", hash = "sha256:3e93e348ab27e712acd46fccd809139e356eb9a31aab641d1a7991a6eb4e6f68"}, -] - -[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.0.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.0.0)", "pytest (>=7.0,<8)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] - [[package]] name = "nbclient" version = "0.10.2" @@ -2974,7 +2436,6 @@ description = "A client library for executing notebooks. Formerly nbconvert's Ex optional = false python-versions = ">=3.9.0" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "nbclient-0.10.2-py3-none-any.whl", hash = "sha256:4ffee11e788b4a27fabeb7955547e4318a5298f34342a4bfd01f2e1faaeadc3d"}, {file = "nbclient-0.10.2.tar.gz", hash = "sha256:90b7fc6b810630db87a6d0c2250b1f0ab4cf4d3c27a299b0cde78a4ed3fd9193"}, @@ -3063,31 +2524,6 @@ files = [ {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, ] -[[package]] -name = "notebook" -version = "7.3.3" -description = "Jupyter Notebook - A web-based notebook environment for interactive computing" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "notebook-7.3.3-py3-none-any.whl", hash = "sha256:b193df0878956562d5171c8e25c9252b8e86c9fcc16163b8ee3fe6c5e3f422f7"}, - {file = "notebook-7.3.3.tar.gz", hash = "sha256:707a313fb882d35f921989eb3d204de942ed5132a44e4aa1fe0e8f24bb9dc25d"}, -] - -[package.dependencies] -jupyter-server = ">=2.4.0,<3" -jupyterlab = ">=4.3.6,<4.4" -jupyterlab-server = ">=2.27.1,<3" -notebook-shim = ">=0.2,<0.3" -tornado = ">=6.2.0" - -[package.extras] -dev = ["hatch", "pre-commit"] -docs = ["myst-parser", "nbsphinx", "pydata-sphinx-theme", "sphinx (>=1.3.6)", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["importlib-resources (>=5.0) ; python_version < \"3.10\"", "ipykernel", "jupyter-server[test] (>=2.4.0,<3)", "jupyterlab-server[test] (>=2.27.1,<3)", "nbval", "pytest (>=7.0)", "pytest-console-scripts", "pytest-timeout", "pytest-tornasync", "requests"] - [[package]] name = "notebook" version = "7.4.7" @@ -3095,7 +2531,6 @@ description = "Jupyter Notebook - A web-based notebook environment for interacti optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "notebook-7.4.7-py3-none-any.whl", hash = "sha256:362b7c95527f7dd3c4c84d410b782872fd9c734fb2524c11dd92758527b6eda6"}, {file = "notebook-7.4.7.tar.gz", hash = "sha256:3f0a04027dfcee8a876de48fba13ab77ec8c12f72f848a222ed7f5081b9e342a"}, @@ -3126,48 +2561,186 @@ files = [ ] [package.dependencies] -jupyter-server = ">=1.8,<3" - -[package.extras] -test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync"] +jupyter-server = ">=1.8,<3" + +[package.extras] +test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync"] + +[[package]] +name = "numexpr" +version = "2.10.2" +description = "Fast numerical expression evaluator for NumPy" +optional = false +python-versions = ">=3.9" +groups = ["main"] +markers = "python_version < \"3.11\"" +files = [ + {file = "numexpr-2.10.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5b0e82d2109c1d9e63fcd5ea177d80a11b881157ab61178ddbdebd4c561ea46"}, + {file = "numexpr-2.10.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3fc2b8035a0c2cdc352e58c3875cb668836018065cbf5752cb531015d9a568d8"}, + {file = "numexpr-2.10.2-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0db5ff5183935d1612653559c319922143e8fa3019007696571b13135f216458"}, + {file = "numexpr-2.10.2-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15f59655458056fdb3a621b1bb8e071581ccf7e823916c7568bb7c9a3e393025"}, + {file = "numexpr-2.10.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ce8cccf944339051e44a49a124a06287fe3066d0acbff33d1aa5aee10a96abb7"}, + {file = "numexpr-2.10.2-cp310-cp310-win32.whl", hash = "sha256:ba85371c9a8d03e115f4dfb6d25dfbce05387002b9bc85016af939a1da9624f0"}, + {file = "numexpr-2.10.2-cp310-cp310-win_amd64.whl", hash = "sha256:deb64235af9eeba59fcefa67e82fa80cfc0662e1b0aa373b7118a28da124d51d"}, + {file = "numexpr-2.10.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6b360eb8d392483410fe6a3d5a7144afa298c9a0aa3e9fe193e89590b47dd477"}, + {file = "numexpr-2.10.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d9a42f5c24880350d88933c4efee91b857c378aaea7e8b86221fff569069841e"}, + {file = "numexpr-2.10.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:83fcb11988b57cc25b028a36d285287d706d1f536ebf2662ea30bd990e0de8b9"}, + {file = "numexpr-2.10.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4213a92efa9770bc28e3792134e27c7e5c7e97068bdfb8ba395baebbd12f991b"}, + {file = "numexpr-2.10.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebdbef5763ca057eea0c2b5698e4439d084a0505d9d6e94f4804f26e8890c45e"}, + {file = "numexpr-2.10.2-cp311-cp311-win32.whl", hash = "sha256:3bf01ec502d89944e49e9c1b5cc7c7085be8ca2eb9dd46a0eafd218afbdbd5f5"}, + {file = "numexpr-2.10.2-cp311-cp311-win_amd64.whl", hash = "sha256:e2d0ae24b0728e4bc3f1d3f33310340d67321d36d6043f7ce26897f4f1042db0"}, + {file = "numexpr-2.10.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5323a46e75832334f1af86da1ef6ff0add00fbacdd266250be872b438bdf2be"}, + {file = "numexpr-2.10.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a42963bd4c62d8afa4f51e7974debfa39a048383f653544ab54f50a2f7ec6c42"}, + {file = "numexpr-2.10.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5191ba8f2975cb9703afc04ae845a929e193498c0e8bcd408ecb147b35978470"}, + {file = "numexpr-2.10.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:97298b14f0105a794bea06fd9fbc5c423bd3ff4d88cbc618860b83eb7a436ad6"}, + {file = "numexpr-2.10.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f9d7805ccb6be2d3b0f7f6fad3707a09ac537811e8e9964f4074d28cb35543db"}, + {file = "numexpr-2.10.2-cp312-cp312-win32.whl", hash = "sha256:cb845b2d4f9f8ef0eb1c9884f2b64780a85d3b5ae4eeb26ae2b0019f489cd35e"}, + {file = "numexpr-2.10.2-cp312-cp312-win_amd64.whl", hash = "sha256:57b59cbb5dcce4edf09cd6ce0b57ff60312479930099ca8d944c2fac896a1ead"}, + {file = "numexpr-2.10.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a37d6a51ec328c561b2ca8a2bef07025642eca995b8553a5267d0018c732976d"}, + {file = "numexpr-2.10.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:81d1dde7dd6166d8ff5727bb46ab42a6b0048db0e97ceb84a121334a404a800f"}, + {file = "numexpr-2.10.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5b3f814437d5a10797f8d89d2037cca2c9d9fa578520fc911f894edafed6ea3e"}, + {file = "numexpr-2.10.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9309f2e43fe6e4560699ef5c27d7a848b3ff38549b6b57194207cf0e88900527"}, + {file = "numexpr-2.10.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ebb73b93f5c4d6994f357fa5a47a9f7a5485577e633b3c46a603cb01445bbb19"}, + {file = "numexpr-2.10.2-cp313-cp313-win32.whl", hash = "sha256:ec04c9a3c050c175348801e27c18c68d28673b7bfb865ef88ce333be523bbc01"}, + {file = "numexpr-2.10.2-cp313-cp313-win_amd64.whl", hash = "sha256:d7a3fc83c959288544db3adc70612475d8ad53a66c69198105c74036182d10dd"}, + {file = "numexpr-2.10.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0495f8111c3633e265248709b8b3b521bbfa646ba384909edd10e2b9a588a83a"}, + {file = "numexpr-2.10.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2aa05ac71bee3b1253e73173c4d7fa96a09a18970c0226f1c2c07a71ffe988dc"}, + {file = "numexpr-2.10.2-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3a23c3002ab330056fbdd2785871937a6f2f2fa85d06c8d0ff74ea8418119d1"}, + {file = "numexpr-2.10.2-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a018a7d81326f4c73d8b5aee61794d7d8514512f43957c0db61eb2a8a86848c7"}, + {file = "numexpr-2.10.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:037859b17a0abe2b489d4c2cfdadd2bf458ec80dd83f338ea5544c7987e06b85"}, + {file = "numexpr-2.10.2-cp39-cp39-win32.whl", hash = "sha256:eb278ccda6f893a312aa0452701bb17d098b7b14eb7c9381517d509cce0a39a3"}, + {file = "numexpr-2.10.2-cp39-cp39-win_amd64.whl", hash = "sha256:734b64c6d6a597601ce9d0ef7b666e678ec015b446f1d1412c23903c021436c3"}, + {file = "numexpr-2.10.2.tar.gz", hash = "sha256:b0aff6b48ebc99d2f54f27b5f73a58cb92fde650aeff1b397c71c8788b4fff1a"}, +] + +[package.dependencies] +numpy = ">=1.23.0" + +[[package]] +name = "numexpr" +version = "2.14.1" +description = "Fast numerical expression evaluator for NumPy" +optional = false +python-versions = ">=3.10" +groups = ["main"] +markers = "python_version >= \"3.11\"" +files = [ + {file = "numexpr-2.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d0fab3fd06a04f6b86102552b26aa5d85e20ac7d8296c15764c726eeabae6cc8"}, + {file = "numexpr-2.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:64ae5dfd62d74a3ef82fe0b37f80527247f3626171ad82025900f46ffca4b39a"}, + {file = "numexpr-2.14.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:955c92b064f9074d2970cf3138f5e3b965be673b82024962ed526f39bc25a920"}, + {file = "numexpr-2.14.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:75440c54fc01e130396650fdf307aa9d41a67dc06ddbfb288971b591c13a395b"}, + {file = "numexpr-2.14.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dde9fa47ed319e1e1728940a539df3cb78326b7754bc7c6ab3152afc91808f9b"}, + {file = "numexpr-2.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76db0bc6267e591ab9c4df405ffb533598e4c88239db7338d11ae9e4b368a85a"}, + {file = "numexpr-2.14.1-cp310-cp310-win32.whl", hash = "sha256:0d1dcbdc4d0374c0d523cee2f94f06b001623cbc1fd163612841017a3495427c"}, + {file = "numexpr-2.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:823cd82c8e7937981339f634e7a9c6a92cb2d0b9d0a5cf627a5e394fffc05377"}, + {file = "numexpr-2.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2d03fcb4644a12f70a14d74006f72662824da5b6128bf1bcd10cc3ed80e64c34"}, + {file = "numexpr-2.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2773ee1133f77009a1fc2f34fe236f3d9823779f5f75450e183137d49f00499f"}, + {file = "numexpr-2.14.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ebe4980f9494b9f94d10d2e526edc29e72516698d3bf95670ba79415492212a4"}, + {file = "numexpr-2.14.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a381e5e919a745c9503bcefffc1c7f98c972c04ec58fc8e999ed1a929e01ba6"}, + {file = "numexpr-2.14.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d08856cfc1b440eb1caaa60515235369654321995dd68eb9377577392020f6cb"}, + {file = "numexpr-2.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03130afa04edf83a7b590d207444f05a00363c9b9ea5d81c0f53b1ea13fad55a"}, + {file = "numexpr-2.14.1-cp311-cp311-win32.whl", hash = "sha256:db78fa0c9fcbaded3ae7453faf060bd7a18b0dc10299d7fcd02d9362be1213ed"}, + {file = "numexpr-2.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:e9b2f957798c67a2428be96b04bce85439bed05efe78eb78e4c2ca43737578e7"}, + {file = "numexpr-2.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ebae0ab18c799b0e6b8c5a8d11e1fa3848eb4011271d99848b297468a39430"}, + {file = "numexpr-2.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:47041f2f7b9e69498fb311af672ba914a60e6e6d804011caacb17d66f639e659"}, + {file = "numexpr-2.14.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d686dfb2c1382d9e6e0ee0b7647f943c1886dba3adbf606c625479f35f1956c1"}, + {file = "numexpr-2.14.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eee6d4fbbbc368e6cdd0772734d6249128d957b3b8ad47a100789009f4de7083"}, + {file = "numexpr-2.14.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3a2839efa25f3c8d4133252ea7342d8f81226c7c4dda81f97a57e090b9d87a48"}, + {file = "numexpr-2.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9f9137f1351b310436662b5dc6f4082a245efa8950c3b0d9008028df92fefb9b"}, + {file = "numexpr-2.14.1-cp312-cp312-win32.whl", hash = "sha256:36f8d5c1bd1355df93b43d766790f9046cccfc1e32b7c6163f75bcde682cda07"}, + {file = "numexpr-2.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:fdd886f4b7dbaf167633ee396478f0d0aa58ea2f9e7ccc3c6431019623e8d68f"}, + {file = "numexpr-2.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:09078ba73cffe94745abfbcc2d81ab8b4b4e9d7bfbbde6cac2ee5dbf38eee222"}, + {file = "numexpr-2.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dce0b5a0447baa7b44bc218ec2d7dcd175b8eee6083605293349c0c1d9b82fb6"}, + {file = "numexpr-2.14.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:06855053de7a3a8425429bd996e8ae3c50b57637ad3e757e0fa0602a7874be30"}, + {file = "numexpr-2.14.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f9366d23a2e991fd5a8b5e61a17558f028ba86158a4552f8f239b005cdf83c"}, + {file = "numexpr-2.14.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c5f1b1605695778896534dfc6e130d54a65cd52be7ed2cd0cfee3981fd676bf5"}, + {file = "numexpr-2.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a4ba71db47ea99c659d88ee6233fa77b6dc83392f1d324e0c90ddf617ae3f421"}, + {file = "numexpr-2.14.1-cp313-cp313-win32.whl", hash = "sha256:638dce8320f4a1483d5ca4fda69f60a70ed7e66be6e68bc23fb9f1a6b78a9e3b"}, + {file = "numexpr-2.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:9fdcd4735121658a313f878fd31136d1bfc6a5b913219e7274e9fca9f8dac3bb"}, + {file = "numexpr-2.14.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:557887ad7f5d3c2a40fd7310e50597045a68e66b20a77b3f44d7bc7608523b4b"}, + {file = "numexpr-2.14.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:af111c8fe6fc55d15e4c7cab11920fc50740d913636d486545b080192cd0ad73"}, + {file = "numexpr-2.14.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:33265294376e7e2ae4d264d75b798a915d2acf37b9dd2b9405e8b04f84d05cfc"}, + {file = "numexpr-2.14.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:83647d846d3eeeb9a9255311236135286728b398d0d41d35dedb532dca807fe9"}, + {file = "numexpr-2.14.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6e575fd3ad41ddf3355d0c7ef6bd0168619dc1779a98fe46693cad5e95d25e6e"}, + {file = "numexpr-2.14.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:67ea4771029ce818573b1998f5ca416bd255156feea017841b86176a938f7d19"}, + {file = "numexpr-2.14.1-cp313-cp313t-win32.whl", hash = "sha256:15015d47d3d1487072d58c0e7682ef2eb608321e14099c39d52e2dd689483611"}, + {file = "numexpr-2.14.1-cp313-cp313t-win_amd64.whl", hash = "sha256:94c711f6d8f17dfb4606842b403699603aa591ab9f6bf23038b488ea9cfb0f09"}, + {file = "numexpr-2.14.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ede79f7ff06629f599081de644546ce7324f1581c09b0ac174da88a470d39c21"}, + {file = "numexpr-2.14.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2eac7a5a2f70b3768c67056445d1ceb4ecd9b853c8eda9563823b551aeaa5082"}, + {file = "numexpr-2.14.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5aedf38d4c0c19d3cecfe0334c3f4099fb496f54c146223d30fa930084bc8574"}, + {file = "numexpr-2.14.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:439ec4d57b853792ebe5456e3160312281c3a7071ecac5532ded3278ede614de"}, + {file = "numexpr-2.14.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e23b87f744e04e302d82ac5e2189ae20a533566aec76a46885376e20b0645bf8"}, + {file = "numexpr-2.14.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:44f84e0e5af219dbb62a081606156420815890e041b87252fbcea5df55214c4c"}, + {file = "numexpr-2.14.1-cp314-cp314-win32.whl", hash = "sha256:1f1a5e817c534539351aa75d26088e9e1e0ef1b3a6ab484047618a652ccc4fc3"}, + {file = "numexpr-2.14.1-cp314-cp314-win_amd64.whl", hash = "sha256:587c41509bc373dfb1fe6086ba55a73147297247bedb6d588cda69169fc412f2"}, + {file = "numexpr-2.14.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:ec368819502b64f190c3f71be14a304780b5935c42aae5bf22c27cc2cbba70b5"}, + {file = "numexpr-2.14.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7e87f6d203ac57239de32261c941e9748f9309cbc0da6295eabd0c438b920d3a"}, + {file = "numexpr-2.14.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dd72d8c2a165fe45ea7650b16eb8cc1792a94a722022006bb97c86fe51fd2091"}, + {file = "numexpr-2.14.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:70d80fcb418a54ca208e9a38e58ddc425c07f66485176b261d9a67c7f2864f73"}, + {file = "numexpr-2.14.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:edea2f20c2040df8b54ee8ca8ebda63de9545b2112872466118e9df4d0ae99f3"}, + {file = "numexpr-2.14.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:790447be6879a6c51b9545f79612d24c9ea0a41d537a84e15e6a8ddef0b6268e"}, + {file = "numexpr-2.14.1-cp314-cp314t-win32.whl", hash = "sha256:538961096c2300ea44240209181e31fae82759d26b51713b589332b9f2a4117e"}, + {file = "numexpr-2.14.1-cp314-cp314t-win_amd64.whl", hash = "sha256:a40b350cd45b4446076fa11843fa32bbe07024747aeddf6d467290bf9011b392"}, + {file = "numexpr-2.14.1.tar.gz", hash = "sha256:4be00b1086c7b7a5c32e31558122b7b80243fe098579b170967da83f3152b48b"}, +] + +[package.dependencies] +numpy = ">=1.23.0" [[package]] name = "numpy" -version = "1.24.4" +version = "2.0.2" description = "Fundamental package for array computing in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["main", "examples"] -markers = "python_version <= \"3.11\"" +markers = "python_version < \"3.11\"" files = [ - {file = "numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64"}, - {file = "numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1"}, - {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4"}, - {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6"}, - {file = "numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc"}, - {file = "numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e"}, - {file = "numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810"}, - {file = "numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254"}, - {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7"}, - {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5"}, - {file = "numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d"}, - {file = "numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694"}, - {file = "numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61"}, - {file = "numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f"}, - {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e"}, - {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc"}, - {file = "numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2"}, - {file = "numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706"}, - {file = "numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400"}, - {file = "numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f"}, - {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9"}, - {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d"}, - {file = "numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835"}, - {file = "numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8"}, - {file = "numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef"}, - {file = "numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a"}, - {file = "numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2"}, - {file = "numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463"}, + {file = "numpy-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:51129a29dbe56f9ca83438b706e2e69a39892b5eda6cedcb6b0c9fdc9b0d3ece"}, + {file = "numpy-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f15975dfec0cf2239224d80e32c3170b1d168335eaedee69da84fbe9f1f9cd04"}, + {file = "numpy-2.0.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8c5713284ce4e282544c68d1c3b2c7161d38c256d2eefc93c1d683cf47683e66"}, + {file = "numpy-2.0.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:becfae3ddd30736fe1889a37f1f580e245ba79a5855bff5f2a29cb3ccc22dd7b"}, + {file = "numpy-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2da5960c3cf0df7eafefd806d4e612c5e19358de82cb3c343631188991566ccd"}, + {file = "numpy-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:496f71341824ed9f3d2fd36cf3ac57ae2e0165c143b55c3a035ee219413f3318"}, + {file = "numpy-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a61ec659f68ae254e4d237816e33171497e978140353c0c2038d46e63282d0c8"}, + {file = "numpy-2.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d731a1c6116ba289c1e9ee714b08a8ff882944d4ad631fd411106a30f083c326"}, + {file = "numpy-2.0.2-cp310-cp310-win32.whl", hash = "sha256:984d96121c9f9616cd33fbd0618b7f08e0cfc9600a7ee1d6fd9b239186d19d97"}, + {file = "numpy-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:c7b0be4ef08607dd04da4092faee0b86607f111d5ae68036f16cc787e250a131"}, + {file = "numpy-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:49ca4decb342d66018b01932139c0961a8f9ddc7589611158cb3c27cbcf76448"}, + {file = "numpy-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:11a76c372d1d37437857280aa142086476136a8c0f373b2e648ab2c8f18fb195"}, + {file = "numpy-2.0.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:807ec44583fd708a21d4a11d94aedf2f4f3c3719035c76a2bbe1fe8e217bdc57"}, + {file = "numpy-2.0.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8cafab480740e22f8d833acefed5cc87ce276f4ece12fdaa2e8903db2f82897a"}, + {file = "numpy-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a15f476a45e6e5a3a79d8a14e62161d27ad897381fecfa4a09ed5322f2085669"}, + {file = "numpy-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13e689d772146140a252c3a28501da66dfecd77490b498b168b501835041f951"}, + {file = "numpy-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9ea91dfb7c3d1c56a0e55657c0afb38cf1eeae4544c208dc465c3c9f3a7c09f9"}, + {file = "numpy-2.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c1c9307701fec8f3f7a1e6711f9089c06e6284b3afbbcd259f7791282d660a15"}, + {file = "numpy-2.0.2-cp311-cp311-win32.whl", hash = "sha256:a392a68bd329eafac5817e5aefeb39038c48b671afd242710b451e76090e81f4"}, + {file = "numpy-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:286cd40ce2b7d652a6f22efdfc6d1edf879440e53e76a75955bc0c826c7e64dc"}, + {file = "numpy-2.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:df55d490dea7934f330006d0f81e8551ba6010a5bf035a249ef61a94f21c500b"}, + {file = "numpy-2.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8df823f570d9adf0978347d1f926b2a867d5608f434a7cff7f7908c6570dcf5e"}, + {file = "numpy-2.0.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9a92ae5c14811e390f3767053ff54eaee3bf84576d99a2456391401323f4ec2c"}, + {file = "numpy-2.0.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:a842d573724391493a97a62ebbb8e731f8a5dcc5d285dfc99141ca15a3302d0c"}, + {file = "numpy-2.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05e238064fc0610c840d1cf6a13bf63d7e391717d247f1bf0318172e759e692"}, + {file = "numpy-2.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0123ffdaa88fa4ab64835dcbde75dcdf89c453c922f18dced6e27c90d1d0ec5a"}, + {file = "numpy-2.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:96a55f64139912d61de9137f11bf39a55ec8faec288c75a54f93dfd39f7eb40c"}, + {file = "numpy-2.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec9852fb39354b5a45a80bdab5ac02dd02b15f44b3804e9f00c556bf24b4bded"}, + {file = "numpy-2.0.2-cp312-cp312-win32.whl", hash = "sha256:671bec6496f83202ed2d3c8fdc486a8fc86942f2e69ff0e986140339a63bcbe5"}, + {file = "numpy-2.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:cfd41e13fdc257aa5778496b8caa5e856dc4896d4ccf01841daee1d96465467a"}, + {file = "numpy-2.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9059e10581ce4093f735ed23f3b9d283b9d517ff46009ddd485f1747eb22653c"}, + {file = "numpy-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:423e89b23490805d2a5a96fe40ec507407b8ee786d66f7328be214f9679df6dd"}, + {file = "numpy-2.0.2-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:2b2955fa6f11907cf7a70dab0d0755159bca87755e831e47932367fc8f2f2d0b"}, + {file = "numpy-2.0.2-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:97032a27bd9d8988b9a97a8c4d2c9f2c15a81f61e2f21404d7e8ef00cb5be729"}, + {file = "numpy-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e795a8be3ddbac43274f18588329c72939870a16cae810c2b73461c40718ab1"}, + {file = "numpy-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b258c385842546006213344c50655ff1555a9338e2e5e02a0756dc3e803dd"}, + {file = "numpy-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fec9451a7789926bcf7c2b8d187292c9f93ea30284802a0ab3f5be8ab36865d"}, + {file = "numpy-2.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9189427407d88ff25ecf8f12469d4d39d35bee1db5d39fc5c168c6f088a6956d"}, + {file = "numpy-2.0.2-cp39-cp39-win32.whl", hash = "sha256:905d16e0c60200656500c95b6b8dca5d109e23cb24abc701d41c02d74c6b3afa"}, + {file = "numpy-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:a3f4ab0caa7f053f6797fcd4e1e25caee367db3112ef2b6ef82d749530768c73"}, + {file = "numpy-2.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7f0a0c6f12e07fa94133c8a67404322845220c06a9e80e85999afe727f7438b8"}, + {file = "numpy-2.0.2-pp39-pypy39_pp73-macosx_14_0_x86_64.whl", hash = "sha256:312950fdd060354350ed123c0e25a71327d3711584beaef30cdaa93320c392d4"}, + {file = "numpy-2.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26df23238872200f63518dd2aa984cfca675d82469535dc7162dc2ee52d9dd5c"}, + {file = "numpy-2.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a46288ec55ebbd58947d31d72be2c63cbf839f0a63b49cb755022310792a3385"}, + {file = "numpy-2.0.2.tar.gz", hash = "sha256:883c987dee1880e2a864ab0dc9892292582510604156762362d9326444636e78"}, ] [[package]] @@ -3177,7 +2750,7 @@ description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.11" groups = ["main", "examples"] -markers = "python_version >= \"3.12\"" +markers = "python_version >= \"3.11\"" files = [ {file = "numpy-2.3.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e78aecd2800b32e8347ce49316d3eaf04aed849cd5b38e0af39f829a4e59f5eb"}, {file = "numpy-2.3.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7fd09cc5d65bda1e79432859c40978010622112e9194e581e3415a3eccc7f43f"}, @@ -3274,12 +2847,112 @@ version = "25.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" -groups = ["dev", "examples"] +groups = ["main", "dev", "examples"] 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 = "2.3.3" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "pandas-2.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:376c6446ae31770764215a6c937f72d917f214b43560603cd60da6408f183b6c"}, + {file = "pandas-2.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e19d192383eab2f4ceb30b412b22ea30690c9e618f78870357ae1d682912015a"}, + {file = "pandas-2.3.3-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5caf26f64126b6c7aec964f74266f435afef1c1b13da3b0636c7518a1fa3e2b1"}, + {file = "pandas-2.3.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd7478f1463441ae4ca7308a70e90b33470fa593429f9d4c578dd00d1fa78838"}, + {file = "pandas-2.3.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4793891684806ae50d1288c9bae9330293ab4e083ccd1c5e383c34549c6e4250"}, + {file = "pandas-2.3.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:28083c648d9a99a5dd035ec125d42439c6c1c525098c58af0fc38dd1a7a1b3d4"}, + {file = "pandas-2.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:503cf027cf9940d2ceaa1a93cfb5f8c8c7e6e90720a2850378f0b3f3b1e06826"}, + {file = "pandas-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523"}, + {file = "pandas-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45"}, + {file = "pandas-2.3.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66"}, + {file = "pandas-2.3.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b"}, + {file = "pandas-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791"}, + {file = "pandas-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151"}, + {file = "pandas-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c"}, + {file = "pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53"}, + {file = "pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35"}, + {file = "pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908"}, + {file = "pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89"}, + {file = "pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98"}, + {file = "pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084"}, + {file = "pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b"}, + {file = "pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713"}, + {file = "pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8"}, + {file = "pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d"}, + {file = "pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac"}, + {file = "pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c"}, + {file = "pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493"}, + {file = "pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee"}, + {file = "pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5"}, + {file = "pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21"}, + {file = "pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78"}, + {file = "pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110"}, + {file = "pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86"}, + {file = "pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc"}, + {file = "pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0"}, + {file = "pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593"}, + {file = "pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c"}, + {file = "pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b"}, + {file = "pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6"}, + {file = "pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3"}, + {file = "pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5"}, + {file = "pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec"}, + {file = "pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7"}, + {file = "pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450"}, + {file = "pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5"}, + {file = "pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788"}, + {file = "pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87"}, + {file = "pandas-2.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c503ba5216814e295f40711470446bc3fd00f0faea8a086cbc688808e26f92a2"}, + {file = "pandas-2.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a637c5cdfa04b6d6e2ecedcb81fc52ffb0fd78ce2ebccc9ea964df9f658de8c8"}, + {file = "pandas-2.3.3-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:854d00d556406bffe66a4c0802f334c9ad5a96b4f1f868adf036a21b11ef13ff"}, + {file = "pandas-2.3.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf1f8a81d04ca90e32a0aceb819d34dbd378a98bf923b6398b9a3ec0bf44de29"}, + {file = "pandas-2.3.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:23ebd657a4d38268c7dfbdf089fbc31ea709d82e4923c5ffd4fbd5747133ce73"}, + {file = "pandas-2.3.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5554c929ccc317d41a5e3d1234f3be588248e61f08a74dd17c9eabb535777dc9"}, + {file = "pandas-2.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:d3e28b3e83862ccf4d85ff19cf8c20b2ae7e503881711ff2d534dc8f761131aa"}, + {file = "pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + [[package]] name = "pandocfilters" version = "1.5.1" @@ -3308,6 +2981,24 @@ files = [ qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] testing = ["docopt", "pytest"] +[[package]] +name = "pathos" +version = "0.3.4" +description = "parallel graph management and execution in heterogeneous computing" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "pathos-0.3.4-py3-none-any.whl", hash = "sha256:fe44883448c05c80d518b61df491b496f6190bb6860253f3254d8c9afb53c340"}, + {file = "pathos-0.3.4.tar.gz", hash = "sha256:bad4912d0ef865654a7cc478da65f2e1d5b69f3d92c4a7d9c9845657783c0754"}, +] + +[package.dependencies] +dill = ">=0.4.0" +multiprocess = ">=0.70.18" +pox = ">=0.3.6" +ppft = ">=1.7.7" + [[package]] name = "pathspec" version = "0.12.1" @@ -3327,7 +3018,7 @@ description = "Pexpect allows easy control of interactive console applications." optional = false python-versions = "*" groups = ["dev"] -markers = "python_version <= \"3.11\" and sys_platform != \"win32\" or sys_platform != \"win32\" and sys_platform != \"emscripten\"" +markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\" or python_version < \"3.11\" and sys_platform != \"win32\"" files = [ {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, @@ -3343,7 +3034,7 @@ description = "Tiny 'shelve'-like database with concurrency support" optional = false python-versions = "*" groups = ["dev"] -markers = "python_version <= \"3.11\"" +markers = "python_version < \"3.11\"" files = [ {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, @@ -3355,8 +3046,8 @@ version = "10.4.0" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.8" -groups = ["examples"] -markers = "python_version <= \"3.11\"" +groups = ["main", "examples"] +markers = "python_version < \"3.11\"" files = [ {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, @@ -3454,8 +3145,8 @@ version = "12.0.0" description = "Python Imaging Library (fork)" optional = false python-versions = ">=3.10" -groups = ["examples"] -markers = "python_version >= \"3.12\"" +groups = ["main", "examples"] +markers = "python_version >= \"3.11\"" files = [ {file = "pillow-12.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:3adfb466bbc544b926d50fe8f4a4e6abd8c6bffd28a26177594e6e9b2b76572b"}, {file = "pillow-12.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1ac11e8ea4f611c3c0147424eae514028b5e9077dd99ab91e1bd7bc33ff145e1"}, @@ -3558,19 +3249,6 @@ test-arrow = ["arro3-compute", "arro3-core", "nanoarrow", "pyarrow"] tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma (>=5)", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "trove-classifiers (>=2024.10.12)"] xmp = ["defusedxml"] -[[package]] -name = "pkgutil-resolve-name" -version = "1.3.10" -description = "Resolve a name to an object." -optional = false -python-versions = ">=3.6" -groups = ["dev"] -markers = "python_version == \"3.8\"" -files = [ - {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, - {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, -] - [[package]] name = "platformdirs" version = "4.3.6" @@ -3578,7 +3256,7 @@ description = "A small Python package for determining appropriate platform-speci optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "python_version <= \"3.11\"" +markers = "python_version < \"3.11\"" files = [ {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, @@ -3596,7 +3274,7 @@ description = "A small Python package for determining appropriate platform-speci optional = false python-versions = ">=3.10" groups = ["dev"] -markers = "python_version >= \"3.12\"" +markers = "python_version >= \"3.11\"" files = [ {file = "platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3"}, {file = "platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312"}, @@ -3607,23 +3285,6 @@ docs = ["furo (>=2025.9.25)", "proselint (>=0.14)", "sphinx (>=8.2.3)", "sphinx- 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.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - [[package]] name = "pluggy" version = "1.6.0" @@ -3631,7 +3292,6 @@ description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, @@ -3679,20 +3339,31 @@ xlsx2csv = ["xlsx2csv (>=0.8.0)"] xlsxwriter = ["xlsxwriter"] [[package]] -name = "prometheus-client" -version = "0.21.1" -description = "Python client for the Prometheus monitoring system." +name = "pox" +version = "0.3.6" +description = "utilities for filesystem exploration and automated builds" optional = false python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" +groups = ["main"] +files = [ + {file = "pox-0.3.6-py3-none-any.whl", hash = "sha256:d48654d0a3dca0c9c02dccae54a53c3870286a5217ad306b2bd94f84e008bc1b"}, + {file = "pox-0.3.6.tar.gz", hash = "sha256:84eeed39600159a62804aacfc00e353edeaae67d8c647ccaaab73a6efed3f605"}, +] + +[[package]] +name = "ppft" +version = "1.7.7" +description = "distributed and parallel Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] files = [ - {file = "prometheus_client-0.21.1-py3-none-any.whl", hash = "sha256:594b45c410d6f4f8888940fe80b5cc2521b305a1fafe1c58609ef715a001f301"}, - {file = "prometheus_client-0.21.1.tar.gz", hash = "sha256:252505a722ac04b0456be05c05f75f45d760c2911ffc45f2a06bcaed9f3ae3fb"}, + {file = "ppft-1.7.7-py3-none-any.whl", hash = "sha256:fb7524db110682de886b4bb5b08f7bf6a38940566074ef2f62521cbbd3864676"}, + {file = "ppft-1.7.7.tar.gz", hash = "sha256:f3f77448cfe24c2b8d2296b6d8732280b25041a3f3e1f551856c6451d3e01b96"}, ] [package.extras] -twisted = ["twisted"] +dill = ["dill (>=0.4.0)"] [[package]] name = "prometheus-client" @@ -3701,7 +3372,6 @@ description = "Python client for the Prometheus monitoring system." optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "prometheus_client-0.23.1-py3-none-any.whl", hash = "sha256:dd1913e6e76b59cfe44e7a4b83e01afc9873c1bdfd2ed8739f1e76aeca115f99"}, {file = "prometheus_client-0.23.1.tar.gz", hash = "sha256:6ae8f9081eaaaf153a2e959d2e6c4f4fb57b12ef76c8c7980202f1e57b48b2ce"}, @@ -3765,7 +3435,7 @@ description = "Run a subprocess in a pseudo terminal" optional = false python-versions = "*" groups = ["dev"] -markers = "sys_platform != \"win32\" and python_version <= \"3.11\" or sys_platform != \"win32\" and sys_platform != \"emscripten\" or os_name != \"nt\"" +markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\" or os_name != \"nt\" or sys_platform != \"win32\" and python_version < \"3.11\"" files = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, @@ -3793,7 +3463,7 @@ description = "C parser in Python" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "implementation_name != \"PyPy\" or python_version <= \"3.11\"" +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"}, @@ -3816,35 +3486,34 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pyparsing" -version = "3.1.4" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" +version = "3.2.5" +description = "pyparsing - Classes and methods to define and execute parsing grammars" optional = false -python-versions = ">=3.6.8" -groups = ["examples"] -markers = "python_version <= \"3.11\"" +python-versions = ">=3.9" +groups = ["main", "examples"] files = [ - {file = "pyparsing-3.1.4-py3-none-any.whl", hash = "sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c"}, - {file = "pyparsing-3.1.4.tar.gz", hash = "sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032"}, + {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 = "pyparsing" -version = "3.2.5" -description = "pyparsing - Classes and methods to define and execute parsing grammars" +name = "pyreadline3" +version = "3.5.4" +description = "A python implementation of GNU readline." optional = false -python-versions = ">=3.9" -groups = ["examples"] -markers = "python_version >= \"3.12\"" +python-versions = ">=3.8" +groups = ["main"] +markers = "sys_platform == \"win32\"" files = [ - {file = "pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e"}, - {file = "pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6"}, + {file = "pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6"}, + {file = "pyreadline3-3.5.4.tar.gz", hash = "sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7"}, ] [package.extras] -diagrams = ["jinja2", "railroad-diagrams"] +dev = ["build", "flake8", "mypy", "pytest", "twine"] [[package]] name = "pytest" @@ -3875,7 +3544,7 @@ 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 = ["dev", "examples"] +groups = ["main", "dev", "examples"] 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"}, @@ -3908,8 +3577,7 @@ version = "2025.2" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" -groups = ["dev"] -markers = "python_version == \"3.8\"" +groups = ["main"] files = [ {file = "pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00"}, {file = "pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3"}, @@ -3922,7 +3590,7 @@ description = "Python for Window Extensions" optional = false python-versions = "*" groups = ["dev"] -markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\" and python_version <= \"3.11\"" +markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\" and python_version < \"3.11\"" files = [ {file = "pywin32-311-cp310-cp310-win32.whl", hash = "sha256:d03ff496d2a0cd4a5893504789d4a15399133fe82517455e78bad62efbb7f0a3"}, {file = "pywin32-311-cp310-cp310-win_amd64.whl", hash = "sha256:797c2772017851984b97180b0bebe4b620bb86328e8a884bb626156295a63b3b"}, @@ -3946,23 +3614,6 @@ files = [ {file = "pywin32-311-cp39-cp39-win_arm64.whl", hash = "sha256:62ea666235135fee79bb154e695f3ff67370afefd71bd7fea7512fc70ef31e3d"}, ] -[[package]] -name = "pywinpty" -version = "2.0.14" -description = "Pseudo terminal support for Windows from Python." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\" and os_name == \"nt\"" -files = [ - {file = "pywinpty-2.0.14-cp310-none-win_amd64.whl", hash = "sha256:0b149c2918c7974f575ba79f5a4aad58bd859a52fa9eb1296cc22aa412aa411f"}, - {file = "pywinpty-2.0.14-cp311-none-win_amd64.whl", hash = "sha256:cf2a43ac7065b3e0dc8510f8c1f13a75fb8fde805efa3b8cff7599a1ef497bc7"}, - {file = "pywinpty-2.0.14-cp312-none-win_amd64.whl", hash = "sha256:55dad362ef3e9408ade68fd173e4f9032b3ce08f68cfe7eacb2c263ea1179737"}, - {file = "pywinpty-2.0.14-cp313-none-win_amd64.whl", hash = "sha256:074fb988a56ec79ca90ed03a896d40707131897cefb8f76f926e3834227f2819"}, - {file = "pywinpty-2.0.14-cp39-none-win_amd64.whl", hash = "sha256:5725fd56f73c0531ec218663bd8c8ff5acc43c78962fab28564871b5fce053fd"}, - {file = "pywinpty-2.0.14.tar.gz", hash = "sha256:18bd9529e4a5daf2d9719aa17788ba6013e594ae94c5a0c27e83df3278b0660e"}, -] - [[package]] name = "pywinpty" version = "3.0.2" @@ -3970,7 +3621,7 @@ description = "Pseudo terminal support for Windows from Python." optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\" and os_name == \"nt\"" +markers = "os_name == \"nt\"" files = [ {file = "pywinpty-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:65db57fd3387d71e8372b6a54269cbcd0f6dfa6d4616a29e0af749ec19f5c558"}, {file = "pywinpty-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:327790d70e4c841ebd9d0f295a780177149aeb405bca44c7115a3de5c2054b23"}, @@ -4178,7 +3829,7 @@ description = "JSON Referencing + Python" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "python_version <= \"3.11\"" +markers = "python_version < \"3.11\"" files = [ {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, @@ -4195,7 +3846,7 @@ description = "JSON Referencing + Python" optional = false python-versions = ">=3.10" groups = ["dev"] -markers = "python_version >= \"3.12\"" +markers = "python_version >= \"3.11\"" files = [ {file = "referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231"}, {file = "referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8"}, @@ -4206,29 +3857,6 @@ 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.4" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c"}, - {file = "requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422"}, -] - -[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 = "requests" version = "2.32.5" @@ -4236,7 +3864,6 @@ description = "Python HTTP for Humans." optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6"}, {file = "requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf"}, @@ -4286,7 +3913,6 @@ description = "Helper functions to syntactically validate strings according to R optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "rfc3987_syntax-1.1.0-py3-none-any.whl", hash = "sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f"}, {file = "rfc3987_syntax-1.1.0.tar.gz", hash = "sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d"}, @@ -4305,7 +3931,7 @@ description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "python_version <= \"3.11\"" +markers = "python_version < \"3.11\"" files = [ {file = "rpds_py-0.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a649dfd735fff086e8a9d0503a9f0c7d01b7912a333c7ae77e1515c08c146dad"}, {file = "rpds_py-0.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f16bc1334853e91ddaaa1217045dd7be166170beec337576818461268a3de67f"}, @@ -4419,7 +4045,7 @@ description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.10" groups = ["dev"] -markers = "python_version >= \"3.12\"" +markers = "python_version >= \"3.11\"" files = [ {file = "rpds_py-0.28.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7b6013db815417eeb56b2d9d7324e64fcd4fa289caeee6e7a78b2e11fc9b438a"}, {file = "rpds_py-0.28.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a4c6b05c685c0c03f80dabaeb73e74218c49deea965ca63f76a752807397207"}, @@ -4567,43 +4193,47 @@ files = [ [[package]] name = "scipy" -version = "1.10.1" +version = "1.13.1" description = "Fundamental algorithms for scientific computing in Python" optional = false -python-versions = "<3.12,>=3.8" +python-versions = ">=3.9" groups = ["main"] -markers = "python_version <= \"3.11\"" +markers = "python_version < \"3.11\"" files = [ - {file = "scipy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7354fd7527a4b0377ce55f286805b34e8c54b91be865bac273f527e1b839019"}, - {file = "scipy-1.10.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:4b3f429188c66603a1a5c549fb414e4d3bdc2a24792e061ffbd607d3d75fd84e"}, - {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1553b5dcddd64ba9a0d95355e63fe6c3fc303a8fd77c7bc91e77d61363f7433f"}, - {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c0ff64b06b10e35215abce517252b375e580a6125fd5fdf6421b98efbefb2d2"}, - {file = "scipy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:fae8a7b898c42dffe3f7361c40d5952b6bf32d10c4569098d276b4c547905ee1"}, - {file = "scipy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0f1564ea217e82c1bbe75ddf7285ba0709ecd503f048cb1236ae9995f64217bd"}, - {file = "scipy-1.10.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d925fa1c81b772882aa55bcc10bf88324dadb66ff85d548c71515f6689c6dac5"}, - {file = "scipy-1.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaea0a6be54462ec027de54fca511540980d1e9eea68b2d5c1dbfe084797be35"}, - {file = "scipy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15a35c4242ec5f292c3dd364a7c71a61be87a3d4ddcc693372813c0b73c9af1d"}, - {file = "scipy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:43b8e0bcb877faf0abfb613d51026cd5cc78918e9530e375727bf0625c82788f"}, - {file = "scipy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5678f88c68ea866ed9ebe3a989091088553ba12c6090244fdae3e467b1139c35"}, - {file = "scipy-1.10.1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:39becb03541f9e58243f4197584286e339029e8908c46f7221abeea4b749fa88"}, - {file = "scipy-1.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bce5869c8d68cf383ce240e44c1d9ae7c06078a9396df68ce88a1230f93a30c1"}, - {file = "scipy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07c3457ce0b3ad5124f98a86533106b643dd811dd61b548e78cf4c8786652f6f"}, - {file = "scipy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:049a8bbf0ad95277ffba9b3b7d23e5369cc39e66406d60422c8cfef40ccc8415"}, - {file = "scipy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cd9f1027ff30d90618914a64ca9b1a77a431159df0e2a195d8a9e8a04c78abf9"}, - {file = "scipy-1.10.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:79c8e5a6c6ffaf3a2262ef1be1e108a035cf4f05c14df56057b64acc5bebffb6"}, - {file = "scipy-1.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51af417a000d2dbe1ec6c372dfe688e041a7084da4fdd350aeb139bd3fb55353"}, - {file = "scipy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b4735d6c28aad3cdcf52117e0e91d6b39acd4272f3f5cd9907c24ee931ad601"}, - {file = "scipy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ff7f37b1bf4417baca958d254e8e2875d0cc23aaadbe65b3d5b3077b0eb23ea"}, - {file = "scipy-1.10.1.tar.gz", hash = "sha256:2cf9dfb80a7b4589ba4c40ce7588986d6d5cebc5457cad2c2880f6bc2d42f3a5"}, + {file = "scipy-1.13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:20335853b85e9a49ff7572ab453794298bcf0354d8068c5f6775a0eabf350aca"}, + {file = "scipy-1.13.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d605e9c23906d1994f55ace80e0125c587f96c020037ea6aa98d01b4bd2e222f"}, + {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfa31f1def5c819b19ecc3a8b52d28ffdcc7ed52bb20c9a7589669dd3c250989"}, + {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26264b282b9da0952a024ae34710c2aff7d27480ee91a2e82b7b7073c24722f"}, + {file = "scipy-1.13.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:eccfa1906eacc02de42d70ef4aecea45415f5be17e72b61bafcfd329bdc52e94"}, + {file = "scipy-1.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:2831f0dc9c5ea9edd6e51e6e769b655f08ec6db6e2e10f86ef39bd32eb11da54"}, + {file = "scipy-1.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:27e52b09c0d3a1d5b63e1105f24177e544a222b43611aaf5bc44d4a0979e32f9"}, + {file = "scipy-1.13.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:54f430b00f0133e2224c3ba42b805bfd0086fe488835effa33fa291561932326"}, + {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e89369d27f9e7b0884ae559a3a956e77c02114cc60a6058b4e5011572eea9299"}, + {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a78b4b3345f1b6f68a763c6e25c0c9a23a9fd0f39f5f3d200efe8feda560a5fa"}, + {file = "scipy-1.13.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45484bee6d65633752c490404513b9ef02475b4284c4cfab0ef946def50b3f59"}, + {file = "scipy-1.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:5713f62f781eebd8d597eb3f88b8bf9274e79eeabf63afb4a737abc6c84ad37b"}, + {file = "scipy-1.13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5d72782f39716b2b3509cd7c33cdc08c96f2f4d2b06d51e52fb45a19ca0c86a1"}, + {file = "scipy-1.13.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:017367484ce5498445aade74b1d5ab377acdc65e27095155e448c88497755a5d"}, + {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:949ae67db5fa78a86e8fa644b9a6b07252f449dcf74247108c50e1d20d2b4627"}, + {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de3ade0e53bc1f21358aa74ff4830235d716211d7d077e340c7349bc3542e884"}, + {file = "scipy-1.13.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2ac65fb503dad64218c228e2dc2d0a0193f7904747db43014645ae139c8fad16"}, + {file = "scipy-1.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:cdd7dacfb95fea358916410ec61bbc20440f7860333aee6d882bb8046264e949"}, + {file = "scipy-1.13.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:436bbb42a94a8aeef855d755ce5a465479c721e9d684de76bf61a62e7c2b81d5"}, + {file = "scipy-1.13.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:8335549ebbca860c52bf3d02f80784e91a004b71b059e3eea9678ba994796a24"}, + {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d533654b7d221a6a97304ab63c41c96473ff04459e404b83275b60aa8f4b7004"}, + {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637e98dcf185ba7f8e663e122ebf908c4702420477ae52a04f9908707456ba4d"}, + {file = "scipy-1.13.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a014c2b3697bde71724244f63de2476925596c24285c7a637364761f8710891c"}, + {file = "scipy-1.13.1-cp39-cp39-win_amd64.whl", hash = "sha256:392e4ec766654852c25ebad4f64e4e584cf19820b980bc04960bca0b0cd6eaa2"}, + {file = "scipy-1.13.1.tar.gz", hash = "sha256:095a87a0312b08dfd6a6155cbbd310a8c51800fc931b8c0b84003014b874ed3c"}, ] [package.dependencies] -numpy = ">=1.19.5,<1.27.0" +numpy = ">=1.22.4,<2.3" [package.extras] -dev = ["click", "doit (>=0.36.0)", "flake8", "mypy", "pycodestyle", "pydevtool", "rich-click", "typing_extensions"] -doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] -test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] +dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] +doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.12.0)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] +test = ["array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] [[package]] name = "scipy" @@ -4612,7 +4242,7 @@ description = "Fundamental algorithms for scientific computing in Python" optional = false python-versions = ">=3.11" groups = ["main"] -markers = "python_version >= \"3.12\"" +markers = "python_version >= \"3.11\"" files = [ {file = "scipy-1.16.3-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:40be6cf99e68b6c4321e9f8782e7d5ff8265af28ef2cd56e9c9b2638fa08ad97"}, {file = "scipy-1.16.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:8be1ca9170fcb6223cc7c27f4305d680ded114a1567c0bd2bfcbf947d1b17511"}, @@ -4702,28 +4332,6 @@ nativelib = ["pyobjc-framework-Cocoa ; sys_platform == \"darwin\"", "pywin32 ; s objc = ["pyobjc-framework-Cocoa ; sys_platform == \"darwin\""] win32 = ["pywin32 ; sys_platform == \"win32\""] -[[package]] -name = "setuptools" -version = "75.3.2" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "setuptools-75.3.2-py3-none-any.whl", hash = "sha256:90ab613b6583fc02d5369cbca13ea26ea0e182d1df2d943ee9cbe81d4c61add9"}, - {file = "setuptools-75.3.2.tar.gz", hash = "sha256:3c1383e1038b68556a382c1e8ded8887cd20141b0eb5708a6c8d277de49364f5"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.5.2) ; sys_platform != \"cygwin\""] -core = ["importlib-metadata (>=6) ; python_version < \"3.10\"", "importlib-resources (>=5.10.2) ; python_version < \"3.9\"", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "ruff (<=0.7.1)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib-metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.12.*)", "pytest-mypy"] - [[package]] name = "setuptools" version = "80.9.0" @@ -4731,7 +4339,6 @@ description = "Easily download, build, install, upgrade, and uninstall Python pa optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922"}, {file = "setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c"}, @@ -4746,13 +4353,148 @@ enabler = ["pytest-enabler (>=2.2)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"] +[[package]] +name = "shapely" +version = "2.0.7" +description = "Manipulation and analysis of geometric objects" +optional = false +python-versions = ">=3.7" +groups = ["main"] +markers = "python_version < \"3.11\"" +files = [ + {file = "shapely-2.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:33fb10e50b16113714ae40adccf7670379e9ccf5b7a41d0002046ba2b8f0f691"}, + {file = "shapely-2.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f44eda8bd7a4bccb0f281264b34bf3518d8c4c9a8ffe69a1a05dabf6e8461147"}, + {file = "shapely-2.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf6c50cd879831955ac47af9c907ce0310245f9d162e298703f82e1785e38c98"}, + {file = "shapely-2.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04a65d882456e13c8b417562c36324c0cd1e5915f3c18ad516bb32ee3f5fc895"}, + {file = "shapely-2.0.7-cp310-cp310-win32.whl", hash = "sha256:7e97104d28e60b69f9b6a957c4d3a2a893b27525bc1fc96b47b3ccef46726bf2"}, + {file = "shapely-2.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:35524cc8d40ee4752520819f9894b9f28ba339a42d4922e92c99b148bed3be39"}, + {file = "shapely-2.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5cf23400cb25deccf48c56a7cdda8197ae66c0e9097fcdd122ac2007e320bc34"}, + {file = "shapely-2.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8f1da01c04527f7da59ee3755d8ee112cd8967c15fab9e43bba936b81e2a013"}, + {file = "shapely-2.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f623b64bb219d62014781120f47499a7adc30cf7787e24b659e56651ceebcb0"}, + {file = "shapely-2.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6d95703efaa64aaabf278ced641b888fc23d9c6dd71f8215091afd8a26a66e3"}, + {file = "shapely-2.0.7-cp311-cp311-win32.whl", hash = "sha256:2f6e4759cf680a0f00a54234902415f2fa5fe02f6b05546c662654001f0793a2"}, + {file = "shapely-2.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:b52f3ab845d32dfd20afba86675c91919a622f4627182daec64974db9b0b4608"}, + {file = "shapely-2.0.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4c2b9859424facbafa54f4a19b625a752ff958ab49e01bc695f254f7db1835fa"}, + {file = "shapely-2.0.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5aed1c6764f51011d69a679fdf6b57e691371ae49ebe28c3edb5486537ffbd51"}, + {file = "shapely-2.0.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73c9ae8cf443187d784d57202199bf9fd2d4bb7d5521fe8926ba40db1bc33e8e"}, + {file = "shapely-2.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9469f49ff873ef566864cb3516091881f217b5d231c8164f7883990eec88b73"}, + {file = "shapely-2.0.7-cp312-cp312-win32.whl", hash = "sha256:6bca5095e86be9d4ef3cb52d56bdd66df63ff111d580855cb8546f06c3c907cd"}, + {file = "shapely-2.0.7-cp312-cp312-win_amd64.whl", hash = "sha256:f86e2c0259fe598c4532acfcf638c1f520fa77c1275912bbc958faecbf00b108"}, + {file = "shapely-2.0.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a0c09e3e02f948631c7763b4fd3dd175bc45303a0ae04b000856dedebefe13cb"}, + {file = "shapely-2.0.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:06ff6020949b44baa8fc2e5e57e0f3d09486cd5c33b47d669f847c54136e7027"}, + {file = "shapely-2.0.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d6dbf096f961ca6bec5640e22e65ccdec11e676344e8157fe7d636e7904fd36"}, + {file = "shapely-2.0.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:adeddfb1e22c20548e840403e5e0b3d9dc3daf66f05fa59f1fcf5b5f664f0e98"}, + {file = "shapely-2.0.7-cp313-cp313-win32.whl", hash = "sha256:a7f04691ce1c7ed974c2f8b34a1fe4c3c5dfe33128eae886aa32d730f1ec1913"}, + {file = "shapely-2.0.7-cp313-cp313-win_amd64.whl", hash = "sha256:aaaf5f7e6cc234c1793f2a2760da464b604584fb58c6b6d7d94144fd2692d67e"}, + {file = "shapely-2.0.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:19cbc8808efe87a71150e785b71d8a0e614751464e21fb679d97e274eca7bd43"}, + {file = "shapely-2.0.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc19b78cc966db195024d8011649b4e22812f805dd49264323980715ab80accc"}, + {file = "shapely-2.0.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd37d65519b3f8ed8976fa4302a2827cbb96e0a461a2e504db583b08a22f0b98"}, + {file = "shapely-2.0.7-cp37-cp37m-win32.whl", hash = "sha256:25085a30a2462cee4e850a6e3fb37431cbbe4ad51cbcc163af0cea1eaa9eb96d"}, + {file = "shapely-2.0.7-cp37-cp37m-win_amd64.whl", hash = "sha256:1a2e03277128e62f9a49a58eb7eb813fa9b343925fca5e7d631d50f4c0e8e0b8"}, + {file = "shapely-2.0.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e1c4f1071fe9c09af077a69b6c75f17feb473caeea0c3579b3e94834efcbdc36"}, + {file = "shapely-2.0.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3697bd078b4459f5a1781015854ef5ea5d824dbf95282d0b60bfad6ff83ec8dc"}, + {file = "shapely-2.0.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e9fed9a7d6451979d914cb6ebbb218b4b4e77c0d50da23e23d8327948662611"}, + {file = "shapely-2.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2934834c7f417aeb7cba3b0d9b4441a76ebcecf9ea6e80b455c33c7c62d96a24"}, + {file = "shapely-2.0.7-cp38-cp38-win32.whl", hash = "sha256:2e4a1749ad64bc6e7668c8f2f9479029f079991f4ae3cb9e6b25440e35a4b532"}, + {file = "shapely-2.0.7-cp38-cp38-win_amd64.whl", hash = "sha256:8ae5cb6b645ac3fba34ad84b32fbdccb2ab321facb461954925bde807a0d3b74"}, + {file = "shapely-2.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4abeb44b3b946236e4e1a1b3d2a0987fb4d8a63bfb3fdefb8a19d142b72001e5"}, + {file = "shapely-2.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cd0e75d9124b73e06a42bf1615ad3d7d805f66871aa94538c3a9b7871d620013"}, + {file = "shapely-2.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7977d8a39c4cf0e06247cd2dca695ad4e020b81981d4c82152c996346cf1094b"}, + {file = "shapely-2.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0145387565fcf8f7c028b073c802956431308da933ef41d08b1693de49990d27"}, + {file = "shapely-2.0.7-cp39-cp39-win32.whl", hash = "sha256:98697c842d5c221408ba8aa573d4f49caef4831e9bc6b6e785ce38aca42d1999"}, + {file = "shapely-2.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:a3fb7fbae257e1b042f440289ee7235d03f433ea880e73e687f108d044b24db5"}, + {file = "shapely-2.0.7.tar.gz", hash = "sha256:28fe2997aab9a9dc026dc6a355d04e85841546b2a5d232ed953e3321ab958ee5"}, +] + +[package.dependencies] +numpy = ">=1.14,<3" + +[package.extras] +docs = ["matplotlib", "numpydoc (==1.1.*)", "sphinx", "sphinx-book-theme", "sphinx-remove-toctrees"] +test = ["pytest", "pytest-cov"] + +[[package]] +name = "shapely" +version = "2.1.2" +description = "Manipulation and analysis of geometric objects" +optional = false +python-versions = ">=3.10" +groups = ["main"] +markers = "python_version >= \"3.11\"" +files = [ + {file = "shapely-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7ae48c236c0324b4e139bea88a306a04ca630f49be66741b340729d380d8f52f"}, + {file = "shapely-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eba6710407f1daa8e7602c347dfc94adc02205ec27ed956346190d66579eb9ea"}, + {file = "shapely-2.1.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ef4a456cc8b7b3d50ccec29642aa4aeda959e9da2fe9540a92754770d5f0cf1f"}, + {file = "shapely-2.1.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e38a190442aacc67ff9f75ce60aec04893041f16f97d242209106d502486a142"}, + {file = "shapely-2.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:40d784101f5d06a1fd30b55fc11ea58a61be23f930d934d86f19a180909908a4"}, + {file = "shapely-2.1.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f6f6cd5819c50d9bcf921882784586aab34a4bd53e7553e175dece6db513a6f0"}, + {file = "shapely-2.1.2-cp310-cp310-win32.whl", hash = "sha256:fe9627c39c59e553c90f5bc3128252cb85dc3b3be8189710666d2f8bc3a5503e"}, + {file = "shapely-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:1d0bfb4b8f661b3b4ec3565fa36c340bfb1cda82087199711f86a88647d26b2f"}, + {file = "shapely-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:91121757b0a36c9aac3427a651a7e6567110a4a67c97edf04f8d55d4765f6618"}, + {file = "shapely-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:16a9c722ba774cf50b5d4541242b4cce05aafd44a015290c82ba8a16931ff63d"}, + {file = "shapely-2.1.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cc4f7397459b12c0b196c9efe1f9d7e92463cbba142632b4cc6d8bbbbd3e2b09"}, + {file = "shapely-2.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:136ab87b17e733e22f0961504d05e77e7be8c9b5a8184f685b4a91a84efe3c26"}, + {file = "shapely-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:16c5d0fc45d3aa0a69074979f4f1928ca2734fb2e0dde8af9611e134e46774e7"}, + {file = "shapely-2.1.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6ddc759f72b5b2b0f54a7e7cde44acef680a55019eb52ac63a7af2cf17cb9cd2"}, + {file = "shapely-2.1.2-cp311-cp311-win32.whl", hash = "sha256:2fa78b49485391224755a856ed3b3bd91c8455f6121fee0db0e71cefb07d0ef6"}, + {file = "shapely-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:c64d5c97b2f47e3cd9b712eaced3b061f2b71234b3fc263e0fcf7d889c6559dc"}, + {file = "shapely-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fe2533caae6a91a543dec62e8360fe86ffcdc42a7c55f9dfd0128a977a896b94"}, + {file = "shapely-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ba4d1333cc0bc94381d6d4308d2e4e008e0bd128bdcff5573199742ee3634359"}, + {file = "shapely-2.1.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0bd308103340030feef6c111d3eb98d50dc13feea33affc8a6f9fa549e9458a3"}, + {file = "shapely-2.1.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1e7d4d7ad262a48bb44277ca12c7c78cb1b0f56b32c10734ec9a1d30c0b0c54b"}, + {file = "shapely-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e9eddfe513096a71896441a7c37db72da0687b34752c4e193577a145c71736fc"}, + {file = "shapely-2.1.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:980c777c612514c0cf99bc8a9de6d286f5e186dcaf9091252fcd444e5638193d"}, + {file = "shapely-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9111274b88e4d7b54a95218e243282709b330ef52b7b86bc6aaf4f805306f454"}, + {file = "shapely-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:743044b4cfb34f9a67205cee9279feaf60ba7d02e69febc2afc609047cb49179"}, + {file = "shapely-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b510dda1a3672d6879beb319bc7c5fd302c6c354584690973c838f46ec3e0fa8"}, + {file = "shapely-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8cff473e81017594d20ec55d86b54bc635544897e13a7cfc12e36909c5309a2a"}, + {file = "shapely-2.1.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe7b77dc63d707c09726b7908f575fc04ff1d1ad0f3fb92aec212396bc6cfe5e"}, + {file = "shapely-2.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7ed1a5bbfb386ee8332713bf7508bc24e32d24b74fc9a7b9f8529a55db9f4ee6"}, + {file = "shapely-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a84e0582858d841d54355246ddfcbd1fce3179f185da7470f41ce39d001ee1af"}, + {file = "shapely-2.1.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dc3487447a43d42adcdf52d7ac73804f2312cbfa5d433a7d2c506dcab0033dfd"}, + {file = "shapely-2.1.2-cp313-cp313-win32.whl", hash = "sha256:9c3a3c648aedc9f99c09263b39f2d8252f199cb3ac154fadc173283d7d111350"}, + {file = "shapely-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:ca2591bff6645c216695bdf1614fca9c82ea1144d4a7591a466fef64f28f0715"}, + {file = "shapely-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2d93d23bdd2ed9dc157b46bc2f19b7da143ca8714464249bef6771c679d5ff40"}, + {file = "shapely-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:01d0d304b25634d60bd7cf291828119ab55a3bab87dc4af1e44b07fb225f188b"}, + {file = "shapely-2.1.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8d8382dd120d64b03698b7298b89611a6ea6f55ada9d39942838b79c9bc89801"}, + {file = "shapely-2.1.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:19efa3611eef966e776183e338b2d7ea43569ae99ab34f8d17c2c054d3205cc0"}, + {file = "shapely-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:346ec0c1a0fcd32f57f00e4134d1200e14bf3f5ae12af87ba83ca275c502498c"}, + {file = "shapely-2.1.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6305993a35989391bd3476ee538a5c9a845861462327efe00dd11a5c8c709a99"}, + {file = "shapely-2.1.2-cp313-cp313t-win32.whl", hash = "sha256:c8876673449f3401f278c86eb33224c5764582f72b653a415d0e6672fde887bf"}, + {file = "shapely-2.1.2-cp313-cp313t-win_amd64.whl", hash = "sha256:4a44bc62a10d84c11a7a3d7c1c4fe857f7477c3506e24c9062da0db0ae0c449c"}, + {file = "shapely-2.1.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:9a522f460d28e2bf4e12396240a5fc1518788b2fcd73535166d748399ef0c223"}, + {file = "shapely-2.1.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1ff629e00818033b8d71139565527ced7d776c269a49bd78c9df84e8f852190c"}, + {file = "shapely-2.1.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f67b34271dedc3c653eba4e3d7111aa421d5be9b4c4c7d38d30907f796cb30df"}, + {file = "shapely-2.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:21952dc00df38a2c28375659b07a3979d22641aeb104751e769c3ee825aadecf"}, + {file = "shapely-2.1.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1f2f33f486777456586948e333a56ae21f35ae273be99255a191f5c1fa302eb4"}, + {file = "shapely-2.1.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cf831a13e0d5a7eb519e96f58ec26e049b1fad411fc6fc23b162a7ce04d9cffc"}, + {file = "shapely-2.1.2-cp314-cp314-win32.whl", hash = "sha256:61edcd8d0d17dd99075d320a1dd39c0cb9616f7572f10ef91b4b5b00c4aeb566"}, + {file = "shapely-2.1.2-cp314-cp314-win_amd64.whl", hash = "sha256:a444e7afccdb0999e203b976adb37ea633725333e5b119ad40b1ca291ecf311c"}, + {file = "shapely-2.1.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:5ebe3f84c6112ad3d4632b1fd2290665aa75d4cef5f6c5d77c4c95b324527c6a"}, + {file = "shapely-2.1.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5860eb9f00a1d49ebb14e881f5caf6c2cf472c7fd38bd7f253bbd34f934eb076"}, + {file = "shapely-2.1.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b705c99c76695702656327b819c9660768ec33f5ce01fa32b2af62b56ba400a1"}, + {file = "shapely-2.1.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a1fd0ea855b2cf7c9cddaf25543e914dd75af9de08785f20ca3085f2c9ca60b0"}, + {file = "shapely-2.1.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:df90e2db118c3671a0754f38e36802db75fe0920d211a27481daf50a711fdf26"}, + {file = "shapely-2.1.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:361b6d45030b4ac64ddd0a26046906c8202eb60d0f9f53085f5179f1d23021a0"}, + {file = "shapely-2.1.2-cp314-cp314t-win32.whl", hash = "sha256:b54df60f1fbdecc8ebc2c5b11870461a6417b3d617f555e5033f1505d36e5735"}, + {file = "shapely-2.1.2-cp314-cp314t-win_amd64.whl", hash = "sha256:0036ac886e0923417932c2e6369b6c52e38e0ff5d9120b90eef5cd9a5fc5cae9"}, + {file = "shapely-2.1.2.tar.gz", hash = "sha256:2ed4ecb28320a433db18a5bf029986aa8afcfd740745e78847e330d5d94922a9"}, +] + +[package.dependencies] +numpy = ">=1.21" + +[package.extras] +docs = ["matplotlib", "numpydoc (==1.1.*)", "sphinx", "sphinx-book-theme", "sphinx-remove-toctrees"] +test = ["pytest", "pytest-cov", "scipy-doctest"] + [[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 = ["dev", "examples"] +groups = ["main", "dev", "examples"] files = [ {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, @@ -4770,19 +4512,6 @@ files = [ {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, ] -[[package]] -name = "soupsieve" -version = "2.7" -description = "A modern CSS selector implementation for Beautiful Soup." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4"}, - {file = "soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a"}, -] - [[package]] name = "soupsieve" version = "2.8" @@ -4790,7 +4519,6 @@ description = "A modern CSS selector implementation for Beautiful Soup." optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c"}, {file = "soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f"}, @@ -4845,7 +4573,7 @@ description = "A tiny CSS parser" optional = false python-versions = ">=3.7" groups = ["dev"] -markers = "python_version <= \"3.11\"" +markers = "python_version < \"3.11\"" files = [ {file = "tinycss2-1.2.1-py3-none-any.whl", hash = "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847"}, {file = "tinycss2-1.2.1.tar.gz", hash = "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627"}, @@ -4865,7 +4593,7 @@ description = "A tiny CSS parser" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "python_version >= \"3.12\"" +markers = "python_version >= \"3.11\"" files = [ {file = "tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289"}, {file = "tinycss2-1.4.0.tar.gz", hash = "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7"}, @@ -4878,19 +4606,6 @@ webencodings = ">=0.4" doc = ["sphinx", "sphinx_rtd_theme"] test = ["pytest", "ruff"] -[[package]] -name = "tokenize-rt" -version = "6.0.0" -description = "A wrapper around the stdlib `tokenize` which roundtrips." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "tokenize_rt-6.0.0-py2.py3-none-any.whl", hash = "sha256:d4ff7ded2873512938b4f8cbb98c9b07118f01d30ac585a30d7a88353ca36d22"}, - {file = "tokenize_rt-6.0.0.tar.gz", hash = "sha256:b9711bdfc51210211137499b5e355d3de5ec88a85d2025c520cbb921b5194367"}, -] - [[package]] name = "tokenize-rt" version = "6.2.0" @@ -4898,7 +4613,6 @@ description = "A wrapper around the stdlib `tokenize` which roundtrips." optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "tokenize_rt-6.2.0-py2.py3-none-any.whl", hash = "sha256:a152bf4f249c847a66497a4a95f63376ed68ac6abf092a2f7cfb29d044ecff44"}, {file = "tokenize_rt-6.2.0.tar.gz", hash = "sha256:8439c042b330c553fdbe1758e4a05c0ed460dbbbb24a606f11f0dee75da4cad6"}, @@ -4957,28 +4671,6 @@ files = [ {file = "tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549"}, ] -[[package]] -name = "tornado" -version = "6.4.2" -description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "tornado-6.4.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e828cce1123e9e44ae2a50a9de3055497ab1d0aeb440c5ac23064d9e44880da1"}, - {file = "tornado-6.4.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:072ce12ada169c5b00b7d92a99ba089447ccc993ea2143c9ede887e0937aa803"}, - {file = "tornado-6.4.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a017d239bd1bb0919f72af256a970624241f070496635784d9bf0db640d3fec"}, - {file = "tornado-6.4.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c36e62ce8f63409301537222faffcef7dfc5284f27eec227389f2ad11b09d946"}, - {file = "tornado-6.4.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca9eb02196e789c9cb5c3c7c0f04fb447dc2adffd95265b2c7223a8a615ccbf"}, - {file = "tornado-6.4.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:304463bd0772442ff4d0f5149c6f1c2135a1fae045adf070821c6cdc76980634"}, - {file = "tornado-6.4.2-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:c82c46813ba483a385ab2a99caeaedf92585a1f90defb5693351fa7e4ea0bf73"}, - {file = "tornado-6.4.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:932d195ca9015956fa502c6b56af9eb06106140d844a335590c1ec7f5277d10c"}, - {file = "tornado-6.4.2-cp38-abi3-win32.whl", hash = "sha256:2876cef82e6c5978fde1e0d5b1f919d756968d5b4282418f3146b79b58556482"}, - {file = "tornado-6.4.2-cp38-abi3-win_amd64.whl", hash = "sha256:908b71bf3ff37d81073356a5fadcc660eb10c1476ee6e2725588626ce7e5ca38"}, - {file = "tornado-6.4.2.tar.gz", hash = "sha256:92bad5b4746e9879fd7bf1eb21dce4e3fc5128d71601f80005afa39237ad620b"}, -] - [[package]] name = "tornado" version = "6.5.2" @@ -4986,7 +4678,6 @@ description = "Tornado is a Python web framework and asynchronous networking lib optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "tornado-6.5.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2436822940d37cde62771cff8774f4f00b3c8024fe482e16ca8387b8a2724db6"}, {file = "tornado-6.5.2-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:583a52c7aa94ee046854ba81d9ebb6c81ec0fd30386d96f7640c96dad45a03ef"}, @@ -5040,19 +4731,6 @@ files = [ 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.13.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"}, - {file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"}, -] - [[package]] name = "typing-extensions" version = "4.15.0" @@ -5060,7 +4738,6 @@ description = "Backported and Experimental Type Hints for Python 3.9+" optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" 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"}, @@ -5072,8 +4749,7 @@ version = "2025.2" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" -groups = ["dev"] -markers = "python_version >= \"3.9\"" +groups = ["main", "dev"] files = [ {file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"}, {file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"}, @@ -5122,25 +4798,6 @@ files = [ [package.extras] dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake8-commas", "flake8-comprehensions", "flake8-continuation", "flake8-datetimez", "flake8-docstrings", "flake8-import-order", "flake8-literal", "flake8-modern-annotations", "flake8-noqa", "flake8-pyproject", "flake8-requirements", "flake8-typechecking-import", "flake8-use-fstring", "mypy", "pep8-naming", "types-PyYAML"] -[[package]] -name = "urllib3" -version = "2.2.3" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - [[package]] name = "urllib3" version = "2.5.0" @@ -5148,7 +4805,6 @@ description = "HTTP library with thread-safe connection pooling, file post, and optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, {file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}, @@ -5172,23 +4828,6 @@ files = [ {file = "wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605"}, ] -[[package]] -name = "webcolors" -version = "24.8.0" -description = "A library for working with the color formats defined by HTML and CSS." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "webcolors-24.8.0-py3-none-any.whl", hash = "sha256:fc4c3b59358ada164552084a8ebee637c221e4059267d0f8325b3b560f6c7f0a"}, - {file = "webcolors-24.8.0.tar.gz", hash = "sha256:08b07af286a01bcd30d583a7acadf629583d1f79bfef27dd2c2c5c263817277d"}, -] - -[package.extras] -docs = ["furo", "sphinx", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-notfound-page", "sphinxext-opengraph"] -tests = ["coverage[toml]"] - [[package]] name = "webcolors" version = "24.11.1" @@ -5196,7 +4835,6 @@ description = "A library for working with the color formats defined by HTML and optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "webcolors-24.11.1-py3-none-any.whl", hash = "sha256:515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9"}, {file = "webcolors-24.11.1.tar.gz", hash = "sha256:ecb3d768f32202af770477b8b65f318fa4f566c22948673a977b00d589dd80f6"}, @@ -5214,24 +4852,6 @@ files = [ {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, ] -[[package]] -name = "websocket-client" -version = "1.8.0" -description = "WebSocket client for Python with low level API options" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version <= \"3.11\"" -files = [ - {file = "websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526"}, - {file = "websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da"}, -] - -[package.extras] -docs = ["Sphinx (>=6.0)", "myst-parser (>=2.0.0)", "sphinx-rtd-theme (>=1.1.0)"] -optional = ["python-socks", "wsaccel"] -test = ["websockets"] - [[package]] name = "websocket-client" version = "1.9.0" @@ -5239,7 +4859,6 @@ description = "WebSocket client for Python with low level API options" optional = false python-versions = ">=3.9" groups = ["dev"] -markers = "python_version >= \"3.12\"" files = [ {file = "websocket_client-1.9.0-py3-none-any.whl", hash = "sha256:af248a825037ef591efbf6ed20cc5faa03d3b47b9e5a2230a529eeee1c1fc3ef"}, {file = "websocket_client-1.9.0.tar.gz", hash = "sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98"}, @@ -5268,8 +4887,8 @@ version = "3.20.2" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" -groups = ["dev", "examples"] -markers = "python_version < \"3.10\"" +groups = ["main", "dev", "examples"] +markers = "python_version == \"3.9\"" files = [ {file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"}, {file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"}, @@ -5285,5 +4904,5 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" -python-versions = "^3.8" -content-hash = "17b60b7f0f84b1543ebe4b7a60a1d2f82c598c22c88d20bcce764e657d644611" +python-versions = "^3.9" +content-hash = "4a2f0b1c5894aa64fd619bb5d21363a7895b6ed5f38683efd03c91db167555f4" diff --git a/pyproject.toml b/pyproject.toml index efbf767..6c722a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,11 +7,12 @@ readme = "README.md" packages = [{ include = "MITRotor" }] [tool.poetry.dependencies] -python = "^3.8" +python = "^3.9" numpy = ">=1.16.5" scipy = ">=1.6" unified-momentum-model = {git = "https://github.com/Howland-Lab/Unified-Momentum-Model.git"} pyyaml = "^6.0.1" +floris = "^4.5.1" [tool.poetry.group.dev.dependencies] black = { extras = ["jupyter"], version = "^23.9.1" } From 4253147792b7919a99c53dec46dfed32c0ac9ac9 Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Mon, 22 Dec 2025 15:41:01 -0500 Subject: [PATCH 02/19] First attempt with saving bem solutions --- MITRotor/FlorisInterface.py | 77 ------------ MITRotor/FlorisInterface/FlorisInterface.py | 101 +++++++++++++++ examples/example_05_floris_integration.ipynb | 124 +++++++++++++++++++ 3 files changed, 225 insertions(+), 77 deletions(-) delete mode 100644 MITRotor/FlorisInterface.py create mode 100644 MITRotor/FlorisInterface/FlorisInterface.py create mode 100644 examples/example_05_floris_integration.ipynb diff --git a/MITRotor/FlorisInterface.py b/MITRotor/FlorisInterface.py deleted file mode 100644 index 54da501..0000000 --- a/MITRotor/FlorisInterface.py +++ /dev/null @@ -1,77 +0,0 @@ -import numpy as np -from attrs import define, field -from typing import Literal -# FLORIS Imports -from floris.type_dec import floris_float_type, NDArrayFloat -from floris.core.turbine.operation_models import BaseOperationModel -# MITRotor Imports -from MITRotor.ReferenceTurbines import IEA15MW -from MITRotor.RotorDefinition import RotorDefinition -from MITRotor.Geometry import BEMGeometry -from MITRotor.Momentum import UnifiedMomentum -from MITRotor.BEMSolver import BEM, BEMSolution - -@define -class MITRotorTurbine(BaseOperationModel): - """ - A turbine operation model that calls MITRotor. - """ - # user can define a BEM model if they want a different rotor, momentum model, or geometry - default_bem = BEM( - rotor=IEA15MW(), - momentum_model = UnifiedMomentum(averaging = "rotor"), - geometry = BEMGeometry(Nr = 10, Ntheta = 20), - ) - bem_model = field(init = False, default = default_bem, type = BEM) - # save most recent solution by unique floris arguments - _bem_solution: BEMSolution = field(init=False, default=None) - _last_key: bytes = field(init=False, default=None) - - def _get_solution_key(self, velocities: np.ndarray) -> bytes: # TODO: add more inputs - # Fast, deterministic, and explicit - return velocities.tobytes() - - def _get_solution(self, - power_thrust_table, - velocities, - air_density=None, - ): - # create cache key for current inputs - key = self._velocity_key(velocities) # TODO: add more inputs - # update solution if conditions are different - if key != self._last_key: - self._bem_solution = self.bem_model( # TODO: make sure these inputs are right - power_thrust_table, - velocities, - air_density, - ) - self._last_key = key - return self._bem_solution - - def power( - self, - velocities: NDArrayFloat, - turbulence_intensities: NDArrayFloat, - yaw_angles: NDArrayFloat, - tilt_angles: NDArrayFloat, - **_ - ) -> NDArrayFloat: - return self._get_solution( - power_thrust_table, velocities, air_density - ).power - - - def thrust_coefficient( - self, - velocities: NDArrayFloat, - **_ - ) -> NDArrayFloat: - return self._get_solution(power_thrust_table, velocities, air_density).power - - - def axial_induction( - self, - velocities: NDArrayFloat, - **_ - ) -> NDArrayFloat: - return self._get_solution(power_thrust_table, velocities, air_density).power \ No newline at end of file diff --git a/MITRotor/FlorisInterface/FlorisInterface.py b/MITRotor/FlorisInterface/FlorisInterface.py new file mode 100644 index 0000000..b04e131 --- /dev/null +++ b/MITRotor/FlorisInterface/FlorisInterface.py @@ -0,0 +1,101 @@ +import numpy as np +from attrs import define, field +from typing import Literal, Optional +from scipy.interpolate import interp1d +# FLORIS Imports +from floris.type_dec import floris_float_type, NDArrayFloat +from floris.core.turbine.operation_models import BaseOperationModel +from floris.core.rotor_velocity import average_velocity +# MITRotor Imports +from MITRotor.ReferenceTurbines import IEA15MW +from MITRotor.Momentum import UnifiedMomentum +from MITRotor.Geometry import BEMGeometry +from MITRotor.BEMSolver import BEM, BEMSolution + +def csv_to_interp(csv_file): + # read in csv + data = np.loadtxt(csv_file, delimiter=",", skiprows=1) + # split data into x (wind speed) and y (either pitch or tsr) + x = data[:, 0] + y = data[:, 1] + # sort by x (wind speed) + idx = np.argsort(x) + x = x[idx] + y = y[idx] + # return interpolator for y + return interp1d(x, y, kind="linear", bounds_error=False, fill_value="extrapolate") + +@define +class MITRotorTurbine(BaseOperationModel): + """ + A turbine operation model that calls MITRotor. + """ + # user can define a BEM model if they want a different rotor, momentum model, or geometry + default_bem = BEM( + rotor=IEA15MW(), + momentum_model = UnifiedMomentum(averaging = "rotor"), + geometry = BEMGeometry(Nr = 10, Ntheta = 20), + ) + bem_model = field(init = False, default = default_bem, type = BEM) + # save most recent solution by unique floris arguments + _bem_sol = field(init=False, default=None, type = Optional[list[BEMSolution]]) + _avg_vels = field(init=False, default=None, type = Optional[NDArrayFloat]) + _last_key = field(init=False, default=None, type = bytes) + # save blade pitch and tsr interpolation objects + # TODO -> figure out how to make csv change with rotor type + _pitch_interp = field(init = False, default = csv_to_interp("pitch_15mw.csv")) + _tsr_interp = field(init = False, default= csv_to_interp("tsr_15mw.csv")) + + def _get_solution_key(self, velocities: np.ndarray) -> bytes: # TODO: add more inputs + # Fast, deterministic, and explicit + return velocities.tobytes() + + def _get_solutions(self, + velocities: NDArrayFloat, + yaw_angles: NDArrayFloat, + tilt_angles: NDArrayFloat, + ): + n_findex, n_turbines = yaw_angles.shape + # create cache key for current inputs + key = self._get_solution_key(velocities) # TODO: add more inputs + # update solution if conditions are different + if key != self._last_key: + self._bem_sol = [None] * n_findex + self._avg_vels = np.empty((n_findex, n_turbines), dtype=velocities.dtype) + self._last_key = key + # loop over flow conditions + for findex in range(n_findex): + cond_vels, cond_yaws, cond_tilts = velocities[findex], yaw_angles[findex], tilt_angles[findex] + rotor_avg_vels = average_velocity(cond_vels, method="cubic-mean") # TODO: does method need to be user input? + pitch_vals = self._pitch_interp(rotor_avg_vels) + tsr_vals = self._tsr_interp(rotor_avg_vels) + self._bem_sol[findex] = self.bem_model(pitch_vals, tsr_vals, yaw = cond_yaws, tilt = cond_tilts) + self._avg_vels[findex] = rotor_avg_vels + + return self._bem_sol + + def power(self, + velocities: NDArrayFloat, + yaw_angles: NDArrayFloat, + tilt_angles: NDArrayFloat, + **_ + ) -> NDArrayFloat: + return self._get_solutions(velocities, yaw_angles, tilt_angles).Cp() # TODO: what type of averaging do we want? AND make into POWER + + + def thrust_coefficient(self, + velocities: NDArrayFloat, + yaw_angles: NDArrayFloat, + tilt_angles: NDArrayFloat, + **_ + ) -> NDArrayFloat: + return self._get_solutions(velocities, yaw_angles, tilt_angles).Ct() # TODO: what type of averaging do we want? + + + def axial_induction(self, + velocities: NDArrayFloat, + yaw_angles: NDArrayFloat, + tilt_angles: NDArrayFloat, + **_ + ) -> NDArrayFloat: + return self._get_solutions(velocities, yaw_angles, tilt_angles).a() # TODO: what type of averaging do we want? \ No newline at end of file diff --git a/examples/example_05_floris_integration.ipynb b/examples/example_05_floris_integration.ipynb new file mode 100644 index 0000000..5cafc1b --- /dev/null +++ b/examples/example_05_floris_integration.ipynb @@ -0,0 +1,124 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 26, + "id": "eb249327", + "metadata": {}, + "outputs": [], + "source": [ + "from MITRotor.FlorisInterface.FlorisInterface import csv_to_interp\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "9cc53ad8", + "metadata": {}, + "outputs": [], + "source": [ + "def check_interp(tsr_csv, pitch_csv):\n", + " tsr_interp = csv_to_interp(tsr_csv)\n", + " pitch_interp = csv_to_interp(pitch_csv)\n", + " print(type(pitch_interp))\n", + " # interp values\n", + " x_interp_vals = np.linspace(0, 25, num=100)\n", + " tsr_interp_vals = tsr_interp(x_interp_vals)\n", + " pitch_interp_vals = pitch_interp(x_interp_vals)\n", + " # actual values\n", + " tsr_data = np.loadtxt(tsr_csv, delimiter=\",\", skiprows=1)\n", + " pitch_data = np.loadtxt(pitch_csv, delimiter=\",\", skiprows=1)\n", + " # plot\n", + " plt.plot(x_interp_vals, tsr_interp_vals, label = \"TSR Interpolation\")\n", + " plt.plot(x_interp_vals, pitch_interp_vals, label = \"Pitch Interpolation\")\n", + " plt.scatter(tsr_data[:, 0], tsr_data[:, 1], label = \"TSR Data\")\n", + " plt.scatter(pitch_data[:, 0], pitch_data[:, 1], label = \"Pitch Data\")\n", + " plt.legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "08c83a7f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAGdCAYAAACyzRGfAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjcsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvTLEjVAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAXh5JREFUeJzt3Qd4k2XXB/B/926hFFoKpey9FNlDZMtw4UJFUMRPRBQBUV4n+irugQOVVwUHDlCQoaAM2UNGGTKkCLLaQoEOWjpo813nTlOSNmmTNDv/33XlSpM8SZ4+DTwn933OuX00Go0GRERERA7i66g3IiIiImLwQURERA7HkQ8iIiJyKAYfRERE5FAMPoiIiMihGHwQERGRQzH4ICIiIodi8EFEREQO5Q8XU1xcjNOnTyMiIgI+Pj7O3h0iIiIyg/Qszc7ORnx8PHx9fd0r+JDAIyEhwdm7QURERFY4ceIE6tat617Bh4x46HY+MjLS2btDREREZsjKylKDB7rzuFsFH7qpFgk8GHwQERG5F3NSJphwSkRERA7F4IOIiIgcisEHEREROZTL5XwQEXlDSeLly5dRVFTk7F0hskhAQAD8/PxQVQw+iIgcqKCgACkpKcjNzeVxJ7dMJpUy2vDw8Cq9DoMPIiIHNlE8evSo+uYojZgCAwPZTJHcasTu7NmzOHnyJJo0aVKlERAGH0REDhz1kABEeiGEhobyuJPbqVmzJo4dO4bCwsIqBR9MOCUicrDKWk8TuSpbLXvCfwFERETkUFUKPl599VUVBU2cOLH0vry8PIwfPx41atRQCSnDhw9HWlqaLfaViIjIbY0ePRo33XSTy7yOWwYff/75Jz755BO0bdvW4P7HH38cS5Yswfz587F27Vq1UNwtt9xii30lIiInkC+ZFV1eeOEFtd3ChQvRpUsXREVFqfU9WrVqZfDldM6cOaXPkamn2rVr44477sDx48crfH95XrVq1Sza5969exu8tzs6duyYOlZJSUkG97/33nvqmHhd8HHx4kXcfffdmD17NqpXr156f2ZmJj777DO8/fbb6NOnDzp06IAvvvgCmzZtwpYtW2y530RE5CBSGqy7vPvuu2rdLf37pkyZglWrVqlAQka7t23bhh07duDll19WiYn6dM89deoUfvzxRxw6dAi33XabSycJu5qoqCiLgzGPCD5kWmXIkCHo16+fwf3yYZMPmv79zZs3R7169bB582ajr5Wfn69WwtO/2ENqZh7eW3kYr/560C6vT0TkqeLi4kovcuKTb+P698kUu4x4d+/eHU888QSaNWuGpk2bqqmBDz/80OC1dM+VUY9u3bphzJgxKlix5P9+GWlp3749vvrqK9SvX1/t05133ons7OzSaQkZeZcRAt1Ii4wiiH379uH6669X+xwbG4uRI0ciPT3dYMTkkUceUaMmMTExGDhwYOl+z5o1Sz03JCQEDRs2xIIFCwz2a+/eveqLtzwuqQcPPvig+rJuyvLly9GjRw8VSMj2Q4cOxZEjR0ofb9Cggbq+6qqr1PvLvhmbdpHz6KOPPopatWohODhYvabMTuj88ccf6vkSIF5zzTWq0kqOvQR+bhN8fPfdd9i5cydmzJhR7rHU1FRVt142IpM/sDxmjLyOfHB0FylBs4ez2fl4Z+XfmLvpGHILLtvlPYiIrOmdIP8nOfoi72tLElD89ddf6uRurjNnzqipGinZtLRsU07SixYtwtKlS9VFgg3JQxQSdHTt2hVjx44tHZ2Rc0tGRoYKDuRkvn37dnXyl5zE22+/3eC1586dq85lGzduxMcff1x6/7PPPqtGdnbv3q1G/yXgOXDggHosJydHBSoyGyAnfkk9WLlypQpkTMnJycGkSZPUvkhgIFNRN998syrHFhKUCXkd+R1++ukno68zdepUNYok+y3n58aNG6t9OX/+vMF2Tz/9NN566y31fv7+/rj//vvhLBb1+Thx4gQee+wx/P777yq6soVp06apg68j0a89ApDWdSKREB2CE+cvYc3BsxjStrbN34OIyFKXCovQ8rkVDj9w+18ciNBA27V6mjBhAtavX482bdogMTFR5X4MGDBAnaSDgoIMpudl1EEFXSVdXuVbe1hYmEXvJydoyXuQ3BIhIxhyApepHvkiK8GDfMOXoEjngw8+UIHHK6+8Unrf559/rs45f//9txqtEdJA6/XXXy/3njI99MADD6ifX3rpJXUufP/99/HRRx9h3rx5quDiyy+/LP1d5P2GDRuG1157TX0JL2v48OEGt2VfpI/G/v370bp1a/WzkFER/d+jbAAjIzJyLGRURkhKhOybpEHISJSOHJtrr71W/fzUU0+pGQzZZ1udz+028iHTKhKpXn311SpqkotEmzNnzlQ/y8GV+TGJLvVJZGnqwMmHUuYA9S/2IENOQ9rEq5+X7T1tl/cgIvJWcsJdtmwZkpOT8cwzz6gAY/LkyejUqZNBK3kJFiSBUr59y7dwOZ/ISdFSMt2iCzyETOPI+akiMmKxZs0atW+6i6QGCP3pDslXNEZGU8re1o18yHW7du0MgiiZhpIgydT0xuHDhzFixAg1hSPnPvmdRGUJuPpkvyXdQd5Lf/0VOe66fdPRLxCR4yUqO2b2YlHY27dvXzWnpe++++5Tf7wnn3xSRY/yS0v0qYvo5KDLgSz7R3OGoW1r4+O1R7D64Bk17GjLqJ+IyBohAX5qFMIZ72sPjRo1UhcZIZBhfhlN+P7779W5QsjUgkwLiBYtWqiT57hx41T+hiXkXFP2C6ZuusIUyb/QjUSUpTsZC0tHYaw1bNgwNUokIxXSbl/2X0Y87JXkqn/MdM3CKjtm9mLR2VeiTDkw+uSPJENCuvsleUimUaKjo1UkJ0NxEnjIEJyztYqPRGKNUPx7LlcFIEPbakdCiIicRU4CnvpFSL7Jy9SHTA2YIsP/EqxImwYZBbEVmXYpu2qwvL7kRsh+yWi9paRq89577zW4LdM4ukBKpj7kd9UFL5IzIsGWJOCWde7cOfXlXAKPnj17qvs2bNhQ7ncQFa1+LMdOl58igYyQkRDJO3HlUmObdzh95513VMaujHz06tVLTbeYSpJxNO3Uiza6XbYnxdm7Q0TkMaQCRRIfpbJCFs/btWuXSmiUE2H//v1NPk9GzCXJ8rnnnrPp/kiAsXXrVlXlItUs8g1fKjUlCVOmOuTkLKMuK1asUKMyFZ3gdSSJVPIyJD/k+eefVwmhuoRSyW2R3IlRo0appFuZ3pEv35KLYizfo3r16uqL+6effqqmqlavXm2Q/yikekUqZ3SJsZIvU5YEOjJyJLkdsp3ki0iirUx1yWCAxwYf8kGTum8dOfhSWiV/YIkAJfAwle/hDINLgg8Z+cjJZ9ULEZEtSCLjP//8o0YGZCpekh+lyvG3334z+s1fn4x6SL6IrrrDFqT3iFTQtGzZUiVuyvS/TG3ICIEEGpIMK8mxMjogFZrmrLczffp0VfEpuROSWPrtt9+q1xcywiOBjJz7OnbsiFtvvVWlKkjSqTG+vr7qtSSXUmYO5Bi88cYbBtvI6IzkVEpDT9n3G2+80ehrSZWPfOGXQEdGdySYkX3R78Planw0tq63qiKpdpFMZYnw7JF8Kr/udW/+gWPncjFzxFW4oR2nXojIMaSyQEYFpH+DMyoMqGoj51IW7O5tze35Gbbk/O11C8upqZeSMttfOPVCRETkcF4XfAhdye2aQ2dwkVMvREREDuWZKdaVaFE7Ag1iwnA0PQerDqThxvZ1nL1LRETkwlwsQ8HteeXIh37Vyy97WfVCRETkSF4ZfAhd3seaQ2c59UJERORAXht8NI+LQMOaYSi4XIyV+9OcvTtERERew2uDD4OGY5x6ISIichivDT70p17W/n0W2XmFzt4dIiIir+DVwUez2Ag0Kpl6WXXAOSv7EREReRuvDj60Dce0PT+WsuEYEZHVRo8eXeXun7Z4DXc12ka/u7scQ68OPoQu72Pd32eRxakXIiKTJzX5wiYXWUW1cePGePHFF3H5snaNrPfee0+t6qrTu3dvh6yqKu8pa7NYwlH7Zk/Hjh1Tf4ukpCSD+8v+HVyV1wcfTWPD0bhWOAqKZOqFVS9ERKYMGjQIKSkpOHz4MCZPnqxWstUthiZrelgaBLi7goICuJooN/k7eH3wYVD1wqkXIiKTgoKC1CrliYmJahn3fv36YfHixeWG++XntWvXqm/hutES+aYu/vrrLwwdOlQtPBYREYGePXuqpe31vfnmm6hdu7Zacn78+PEoLDS/IEACovbt2+Orr75C/fr11cn4zjvvRHZ2dqX7tm/fPrUab3h4OGJjY9Uqsenp6QYjJo888ogaNYmJicHAgQPV/fIas2bNUs8NCQlBw4YNsWDBAoP92rt3L/r06aMer1GjBh588EFcvHjR5O+xfPly9OjRQwUSsr0cM/3jJAu7iauuukq9v+xb2b+DyM/Px6OPPopatWqpheDkNf/880+Dlenl+atWrcI111yjVuft1q0bDh06BHvy+uBDv+pl3d/pyLzEqhciciBp212Q4/iLDdqFy4nU2Ld/ObF37doVY8eOVSMlcklISMCpU6fQq1cvFcSsXr1aLSd///33l07diDVr1qiTrFzPnTtXTSFYOo0gz1+0aBGWLl2qLhJsyLLzFe1bRkaGCg7kZL59+3Z18k9LS8Ptt99u8NqyTzLttHHjRnz88cel9z/77LNqWfvdu3fj7rvvVgHPgQMH1GM5OTkqUJEl7uXEP3/+fKxcuVIFMqbIcyZNmqT2RQIDX19f3HzzzSguLlaPb9u2TV3L68jv8NNPPxl9nalTp+LHH39U+71z5041XSb7cv78eYPtnn76abz11lvq/fz9/dXfxZ68cm2XsprGRqBJrXAcPnNRNRwb3qGus3eJiLxFYS7wijbx3aH+cxoIDLN6nRM5Ia5YsQITJkwo97iMNsgJWr5Fy0iJzocffqge++677xAQEKDua9q0qcFz5QT9wQcfwM/PD82bN8eQIUPUe0mwYC45QUvAIiMrQkYw5DVefvllk/sm7ymBxyuvvFJ63+eff64Ck7///rt0P5s0aYLXX3+93HvedttteOCBB9TPL730En7//Xe8//77+OijjzBv3jy1FP2XX36JsDDtMZf3GzZsGF577TU1ylKWBDL6ZF9q1qyJ/fv3o3Xr1upnIaMi+r9H2QBGRmTkWMiojJg9e7bat88++wxPPPFE6bZybK699lr181NPPaWOu+yzjJbYA0c+yox+cK0XIiLjZBRBpiTkhCQnszvuuENNc5hLkiNlmkUXeBjTqlUrFXjoyPTLmTOWtUKQ6RZd4GHua8iIhYy2yO+nu0jwI/SnOzp06GD0+TKaUva2buRDrtu1a1caeIju3burIMnU9Ibk1YwYMUJN4cgUlfxO4vjx4zCX7LdMWcl76cix79SpU+m+6bRt29bgeAlLj7slOPJRQvI+3l15GOsOn1VTL1Ehpv9xEBHZTECodhTCGe9roeuuu059k5aRg/j4eDU8b+k0TaW7VSYwkXwE3VSDuax5Dcm/0I1ElKU7GQv9AMKehg0bpnJrZKRCjrXsv4x42CvJVf+YyfESlh53S3Dko0ST2AhV+VJYpMFvf6Xa7YATERmQ/+hl+sPRl5ITjCXkxCs5A/Xq1as08JAApaioqNy36/Xr11uUQGoPxvbt6quvVsmwMsIgv6P+xZyAY8uWLeVut2jRQv0s1zKyItMgOhs3blR5HM2aNSv3WufOnVMjIs888wz69u2rnn/hwoVyv4Mo+3voa9SoUWl+io4ce8k7admyJZyJwYeeIW20866ceiEiqho5iW/dulVVkkjFiHyLlgTLrKwslYwpiY0ytSBVKfaurDBn36SqRpIwZapDTs4yZSE5Lffdd1+FJ3gdSSKVvAzJD3n++edVQqguoVQSUGWqatSoUaqiZs2aNSpXRnJRjOV7SN6L5HJ8+umnSE5OVsm5knyqT6pXZCRJlxibmZlZ7nUkaJKqJMntkO0kX0RyZ3JzczFmzBg4E4MPPUPaapN2NiSnIzOXVS9ERNaaMmWKyt2Qb9iSHCm5CnJClROpTHFIcqPkT8i0QkU5II7aN5nakBECCTQGDBiANm3aqJJaKXWVEYrKTJ8+XSXSyuiOJJZ+++23paMLktwqgYwENx07dsStt96qRjQk6dQYeT95LakGkqmWxx9/vLSfio6MPM2cOROffPKJ2vcbb7zR6GtJlY8kr0qgI6M7EszIvkiA40w+GklbdiESFUs2skRxkmTjaAPfWYdDadl449a2uO2aBIe/PxF5LqkeOHr0qOrRYK8qAnI8yZFYuHChW7Q1t+dn2JLzN0c+TFS9LNubUuU/EhEREZXH4KOMwSXdTjccTkdGruu1ziUiInJ3LLUtQ9Z5aR4XgYOp2fhtfxpu59QLERFVwMWyF9wCRz6M4FovRERE9sPgw4jBJXkfG5PTcSGHUy9ERES2xODDiEY1w9GidiQuF2vw2342HCMiIrIlBh8mDC2temHwQUREZEsMPiqpeuHUCxERkW0x+DChQUwYWtaORFGxBiu41gsREZFzgg9ZzVBax0rnMrnIksG//vpr6eO9e/dWnd70Lw899BDcFRuOEREROTn4qFu3ruoTL/3mZVGgPn36qH7yshKgjixak5KSUnp5/fXX4e4lt5uOnMN5Vr0QkZcq+6Wy7OWFF15Q20mL8S5duqgW2xEREWjVqpVaH0Vnzpw5pc+R9Utkqfo77rhDra1SEf3nyZossi5J586d8eKLLxpdUK0ispicvE5SUpKVR4Mc3mRs2LBhBrdffvllNRoiSwfLh0y3gE5cnHaBNndXPyYMretEYt+pLCzfl4q7Otdz9i4RESkyJbzt6Hmcyc5DrYhgdGoQDT9fH7scHfkiqfP999/jueeeM1iJNjw8HKtWrVKBhJwXbrjhBnWCl1VUf//9d4PXklFzea405pI1Qh5++GHcdtttapXZiug/LyMjA5s2bcKMGTPwxRdfqAXhZHE18oKcD1n5T1bdy8nJUdMvOt988w1iYmLUSnzTpk1TS/dWJD8/Xy1Go39xJUPaaD/Qv3CtFyJyEcv3paDHa6sxYvYWPPZdkrqW23K/PcgXSt1FRjUksNC/T4KPJUuWoHv37mr59mbNmqFp06ZqobUPP/zQ4LV0z5VRj27duqml3WX5+cr+79d/XosWLdTzJACRFXKnTp165dgsX44ePXqo1WhlFd2hQ4fiyJEjpY/LgmjiqquuUq8p6QLizz//RP/+/dX5S35HWXV3586dNj6SZHXwsXfvXvVBCwoKUvkcMsymWzb4rrvuwtdff401a9aowOOrr77CPffcU+HrSeQqf2jdJSEhwUWnXtJx7mK+s3eHiLycBBjjvt6JlMw8g/tTM/PU/fYKQCojgYFMwe/bt8/s55w5c0adQ2QqRS6WqlWrFu6++24sXrxYfSEW8oV40qRJKjVARmNkeufmm29GcXGxelwCHbFy5Uo1ovPTTz+p29nZ2Rg1ahQ2bNigRvObNGmCwYMHq/vJBdZ2kYhW5spknm3BggXqj7V27VoVgDz44IOl27Vp00ZFqH379lVRZ6NGjYy+ngQp8kHRkejXlQKQejVC0aZOFPaeysSKv9I49UJETp1qmb5kP4ytJCL3yaSLPN6/ZZzdpmBMmTBhAtavX6/+709MTFS5HwMGDFDBgXxZ1ZFzh3yBlekT3cj4o48+irCwMKvet3nz5ipAOHfunApGhg8fbvD4559/jpo1a6opIBmRl5+FjIropwhIDqO+Tz/9VI2eyPlNRk/IySMfgYGBaNy4MTp06KBGLdq1a4f33nvP6LaSECSSk5NNvp58KHXVM7qL61a9nHb2rhCRF5Mcj7IjHmUDEHlctnM0CR6WLVum/r9/5plnVIAxefJkdOrUyWD6XRJR5QusjEy89dZbuPrqq1WeSFUXdZMpFHH48GGMGDECDRs2VOeT+vXrq/srS2pNS0tTBRMy4iGj8PJcmdKp7HnkpD4fMpQleRvG6LKJZQTEnemmXjYfOYd0Tr0QkZNIcqktt7MHGeV+4IEH8L///U/lTMiIgySp6sg0iHyBlbwNGfWWEZJx48ZZ/X4HDhxQgYKMZOgKI86fP4/Zs2erJFZdImtBQcXrdMkovpyz5Mu05JLIz/KalT2PHDDtIlMk119/PerVq6eGuebNm4c//vgDK1asUFMrclvmyOQPtmfPHjz++OPo1auX6g3izhKiQ9G2bhT2nMxUVS/3dEl09i4RkReSqhZbbmdvMuogFZCSh2HKU089pQIWOV/IKIglJGdEzjuS2CpBjUy9SEWMBB49e/ZU20gOR9nRe6HLEdGRipmPPvpIncPEiRMnkJ6ebtH+kJ2CD/lD33vvvSpJR4alJKiQwEMyhOUPJQk87777rvqgSd6GzL3J8JsnkNEPCT6W7Ulh8EFETiHltLWjglVyqbG8D5l4iIvSlt06mvT6kOkVOXlLzoeUw86cOROFhYXqHGGKnCskIVTKd5cuXVrh9Epqamppqe3mzZvxyiuvqHOR9J8S0v9DvvxKvoaMuMuUiQQ3+iQvJCQkRFXFSO+q4OBg9Roy3SJFEtdcc43KPZSqHdmOXGDa5bPPPlMNWmSaRQIRCTZ0Hyr5AElijkSeeXl5at5NGoy5Yg5HVdZ62Xr0HM5ms+qFiBxPkkifH6atLiybTqq7LY87OtlUSGnqP//8o76gShKojJJLsPDbb7+pQoWKyKiH5IvoKlGMkYBAAoo6deqo9g6ffPKJmirZtWtX6dS+jH5ICwhphCnJpfK6b7zxhsHr+Pv7q6BIni+9QaRRpu78duHCBTX6MnLkSJUEK4EK2YePRpet4yLkAyZRqGREu1rgcuMHG7D7ZCZeuqk1RnLqhYgsJF/MpLGW9JqQb9zWknJaqWrRTz6VEREJPAa1du8cO3Lfz7Al52+LS229mVS9SPCxbM9pBh9E5DQSYEg5raM6nBLZGle1tWrqRfsPnojIWSTQ6NqoBm5sX0ddM/Agd8LgwwJ1q4eifUI1yETVin2p9vurEBEReTAGH1b2/Fi6xzktjImIiNwdgw8LXd9G245327HzOJPFqRciIiJLMfiwYurlqnraqZdfOfVCRERkMQYfVZh6WbaXUy9ERESWYvBRhaqXP4+dRxqnXoiIiCzC4MMK8dVCcLVu6oWjH0RERBZh8GGlIW3j1TWnXoiIgNGjR6sF3pz9GuQeGHxYaXBJ1cufxy6oRZ6IiDyZBAY+Pj7qIivDNm7cGC+++CIuX76sHpel6OfMmVO6fe/evTFx4kS775e8p26//Pz81OJynTt3Vvsmbb4tIWuXyeskJSXZbX9Ji8GHlWpHheCaxOrq51/3MfGUiBysuAg4uh7Yu0B7LbftbNCgQWpVc1k4dPLkyWolW93CbbKmR7Vq1eAMso6I7NfJkyexadMmPPjgg/jyyy/Rvn17nD592in7RBVj8GGDxNNlbDhGRI60fzHwbmtg7lDgxzHaa7kt99tRUFAQ4uLikJiYiHHjxqFfv35YvHhxuSkT+VlWOZfREN2ohIwqiL/++gtDhw5VAUNERAR69uyJI0eOGLzPm2++qVaqrVGjBsaPH4/CwsIK90teX/ZLntOiRQuMGTNGBSEXL17E1KlTS7dbvnw5evTooYIkeW3ZD/33lsXSxFVXXaVeU0ZvxJ9//qlWcI+JiVFBlqzgu3PnTpsdV2/E4MMGwcf2fy8gJfOSrf4mRESmSYDxw71AVplv9Fkp2vvtHIDoCwkJQUFBQbn7JeiQZe/Hjh2rRiTkkpCQgFOnTqFXr14qiFm9ejV27NiB+++/v3TqRqxZs0YFBHI9d+5cNa2iP51jrlq1auHuu+9WwVFRkXZUKCcnB5MmTcL27duxatUq+Pr64uabb0ZxcbF6fNu2bep65cqVap9/+ukndTs7OxujRo3Chg0bsGXLFjRp0gSDBw9W95N1uKptFcRFBaNj/eoq7+OXvakY00MbNRMR2YVMrSx/EoDGyINynw+w/Cmg+RDA189ufwSNRqNO3itWrMCECRPKPS6jA5IXEhoaqkYkdD788EP12HfffYeAgAB1X9OmTQ2eKzkbH3zwgcrfaN68OYYMGaLeSwIZS8nzJUA4d+6cCkaGDx9u8Pjnn3+OmjVrYv/+/WjdurX6WcioiP5+9+nTx+B5n376qRo9kdEdGT0hy3Hkw0YNx35hyS0R2du/m8qPeBjQAFmntNvZwdKlSxEeHo7g4GBcf/31uOOOO1Teh7kkkVOmWXSBhzGtWrVSgYeOTKWcOXPG6iBJyBSKkFyVESNGoGHDhmrap379+ur+48ePV/g6aWlpKviREQ8JnuS5MqVT2fPINI58VNH1bWpj+tL92PHvBZzOuKR6gBAR2cXFNNtuZ6HrrrsOs2bNUqMa8fHx8Pf3t3iapjJlAxMJHHTTIpY6cOCAChRkJEMMGzZM5avMnj1b7b+8rox4GJs60idTLjJ6ItNJ8nyZNpJppcqeR6Zx5KOKYiOD0TExWv3M0Q8isqvwWNtuZ6GwsDBVYluvXr1KAw8JUHS5Fjpt27bF+vXrK00gtQUZLZk3b55KgpXcDgkeDh06hGeeeQZ9+/ZViakXLlwot8+i7H5v3LgRjz76qMrzkJEZCT7S09Pt/jt4MgYfNjCkLdd6ISIHSOwGREqDQ+00Qnk+QGQd7XZOJlMaW7duVVUucqKWUYZHHnkEWVlZuPPOO1XSp0yDfPXVVyooqAqZXklNTVVJojLaIbkc3bp1U1Mkr776amkuiYyASL5GcnKySniV5FN9khciozNSFSNTLbo+ITLdIvspry2/kySymjOKQ6Yx+LCB61vHQaYUdx3PwKkMVr0QkZ1IEumg10pulA1ASm4PetWuyabmmjJlisrdaNmypUrklPwIOfnLSV/yJaRctUOHDmoKpKIcEHNIQCO5IXXq1FHTIZ988omaKtm1a5e6X8johyS6SoWNTLU8/vjjpT1KdGQ0Z+bMmer5Mi1z4403qvs/++wzNUpy9dVXY+TIkWoURAIVsp6PRpeR4yLkQyTRqkScMlfnLm7/ZDO2HT2PZ4a0wAM9Gzp7d4jIBeXl5eHo0aOqn4QkbVpNymml6kU/+VRGPCTwaHmDTfaVyNLPsCXnbyac2sjQtrVV8LF0TwqDDyKyLwkwpJxWqlokuVRyPGSqxQVGPIjMwWkXGxlUMvWSdCIDJy/k2upliYiMk0CjQU+gza3aawYe5EYYfNhIrYhgdG6grXr5dW+qrV6WiIjI4zD4sEPDsaVsOEZERGQSgw8bGtg6Dr4+wO4TGThxnlMvRERExjD4sPnUi7aTHhuOEZEpLlZkSOTwzy6DDzs1HGPwQURl6fpZ5OZyZJTck66lvP76O9Zgqa0dql6e+3kfdp/MVFMvCdGhtn4LInJT8h+2rIaqWyhNVn3VLXpG5OqkS+3Zs2fV59bSdX3KYvBhYzHhQejSsAY2HTmHZXtT8NC1jWz9FkTkxnRLtVu7UiuRM0mnWFnbp6pBs0XBh6xmKBfp1S9kgZ3nnntOLa2s63w2efJk1cI2Pz8fAwcOxEcffYTYWPsscuTKUy8q+NjD4IOIDMl/2tLyW9pzO2KBNSJbksX3JACpKouCj7p166pFemSRHUk6mTt3rup9L/3zJRCRXvnLli3D/PnzVYtVWUTolltuUSsCepNBreLw7KJ92HsqE8fP5aJeDU69EFH5KZiqzpsTee3aLtHR0WpxnltvvVUtHiRLGMvP4uDBg2rZ4s2bN6NLly4evbZLWXf/bws2Jp/Dk4OaY1xvTr0QEZFny7Lg/G312ElRUZGaXsnJyVGrCMpKgTKE2K9fv9JtmjdvruaGJPgwRaZnZIf1L55gSBtZ9hpYtldv4SciIiKyPPjYu3cvwsPDERQUhIceeggLFy5USyanpqaquSDJ5NYn+R7ymCkzZsxQkZLukpCQ4BF/loGtYuHn64N9p7Lw77kcZ+8OERGR+wYfzZo1Q1JSErZu3Ypx48Zh1KhR2L9/v9U7MG3aNDVEo7ucOHECnqBGeBC6NdI2HJOqFyIiIrIy+JDRjcaNG6NDhw5q1KJdu3Z47733VPmYNB/JyMgw2D4tLa20tMwYGUGRuSH9i6cYXLLWi1S9EBERkZavLZqOSN6GBCPSvW/VqlWljx06dAjHjx9XOSHeaGCrODX18tfpLBxN59QLERGRxaW2MkUiPT0kiTQ7O1tVtvzxxx9YsWKFytcYM2YMJk2apCpgZARjwoQJKvAwt9LF00SHBaqpl/WH01W79fHXNXb2LhEREblX8CEd+e69916kpKSoYKNt27Yq8Ojfv796/J133lHNR4YPH27QZMybDW1bWwUfMvXC4IOIiMgGfT5szVP6fOhcyCnANS+vRFGxBqsnX4uGNcOdvUtERETu2eeDzFM9LBDdG8eon7nSLREREYMPhxhaUvWylFUvREREHPlwhAGtYuHv64ODqdk4cvYiP3ZEROTVOO3iANVC9aZeOPpBRERejsGHgwxpW9JwjN1OiYjIyzH4cJCBLeMQ4Kedekk+k+2otyUiInI5DD4cJCo0oHTqZdke0wvtEREReToGHw40pKTqhSW3RETkzRh8ONCAkqmXQ2nZOJzGqRciIvJODD4cPPXSs0lN9TMTT4mIyFsx+HCwwSVTL7LWCxERkTdi8OFg/VvGItDPF4fPXMTfnHohIiIvxODDwaJCZOpFV/XC0Q8iIvI+DD6c3HDMxRYVJiIisjsGH07Qr2TqJVlNvXCtFyIi8i4MPpwgMjgAvZrqpl5OO2MXiIiInIbBh5Nw6oWIiLwVgw8n6dciFoH+vjhyNket90JEROQtGHw4SURwAK5tqm04xnbrRETkTRh8ONFQXdXLHla9EBGR92Dw4UR9S6Ze/knn1AsREXkPBh9OFB7kj94lUy9sOEZERN6CwYeTseqFiIi8DYMPF5l6OZqeg/0pWc7eHSIiIrtj8OECUy/XNWPVCxEReQ8GHy5gSNt4dc2qFyIi8gYMPlxA3+a1EOTvi2PncvHXaU69EBGRZ2Pw4QLC1NRLrdKVbomIiDwZgw8Xq3qRbqcajcbZu0NERGQ3DD5cRJ/mtRAc4It/OfVCREQejsGHC029SAAilu7h1AsREXkui4KPGTNmoGPHjoiIiECtWrVw00034dChQwbb9O7dGz4+PgaXhx56yNb77ZEGtylZ62XvaU69EBGRx7Io+Fi7di3Gjx+PLVu24Pfff0dhYSEGDBiAnJwcg+3Gjh2LlJSU0svrr79u6/326KmXE+cvYd8pVr0QEZFn8rdk4+XLlxvcnjNnjhoB2bFjB3r16lV6f2hoKOLi4my3l14iNNAffZvHqoqXpXtPo03dKGfvEhERkWvlfGRmZqrr6Ohog/u/+eYbxMTEoHXr1pg2bRpyc3NNvkZ+fj6ysrIMLt6sdK2XPax6ISIiz2TRyIe+4uJiTJw4Ed27d1dBhs5dd92FxMRExMfHY8+ePXjyySdVXshPP/1kMo9k+vTp1u6Gx5F+HyEBfjh54RL2nMxEu4Rqzt4lIiIim/LRWNlUYty4cfj111+xYcMG1K1b1+R2q1evRt++fZGcnIxGjRoZHfmQi46MfCQkJKhRlcjISHij8fN2qpGP/+vVENMGt3D27hAREVVKzt9RUVFmnb+tmnZ55JFHsHTpUqxZs6bCwEN07txZXUvwYUxQUJDaSf2LtxtaUvUiJbdsOEZERJ7GouBDToQSeCxcuFCNaDRo0KDS5yQlJanr2rW1J1SqXO9mtRAa6IdTGZew+6Q2r4aIiMgrgw8ps/36668xb9481esjNTVVXS5duqQeP3LkCF566SVV/XLs2DEsXrwY9957r6qEadu2rb1+B48TEuiHvi1i1c/L9px29u4QERE5L/iYNWuWmsuRRmIykqG7fP/99+rxwMBArFy5UvX+aN68OSZPnozhw4djyZIltt1rLzCkjbZU+Ze9qZx6ISIi7612qSz/QBJFpREZ2XbqJelEBq6qV52HlYiIPALXdnFRwQF+6Fc69cK1XoiIyHMw+HCDhmO/7GXVCxEReQ4GHy7s2qY1ERboh9OZedh5PMPZu0NERGQTDD5cfeqlZWzp6AcREZEnYPDh4oaUNByT4KO42KpmtERERC6FwYeL69W0JsKD/JGSmYddJzj1QkREVVBcBBxdD+xdoL2W2+60sBw5suqlFhYlnVZVLx0SWXJLRERW2L8YWP4kkKXXvDIyHhj0GtDyBjgSRz7cwJC28eqaUy9ERGR14PHDvYaBh8hK0d4vjzsQgw830LNJDCKC/JGaJVUvF5y9O0RE5E6Ki7QjHjCWN1hy3/KnHDoFw+DDTaZe+pdUvSxj1QsREVmSx/HvpvIjHgY0QNYp7XYOwuDDDRuOseqFiIgUmS55tzUwdyjw4xjttdzWTaNcugDs+hpmuZgGR2HCqZvoUTL1kpaVjx3HL6Bj/Whn7xIREblCHgfKTKfIKMcPI4HE7sCpHcDlPPNeL1w7wu4IHPlwE0H+fujfimu9EBERKsnjKPHvRm3gEdsKCI6q4LD5AJF1gMRuDju0DD7cyFBOvRARkVl5HCUGvwU8tBG44QNtkKEu+kpuD3oV8PWDozD4cCM9GtdERLA/zmTnY/u/rHohIvJaF83MzwipBvj4aPt43P4lEKnNHzTo8yH3O7jPB3M+3Eigvy8GtorDgh0nsWzPaXRqwLwPIiKPm075d5M2uJAcDJkKKTsicWwjsElGMizM45AAo/mQyl/fARh8uOFaLxJ8/LIvFc8NawU/37JDaERE5HEdSFsMA5JXAevfBI5vNuPFJI8jvnwehwQaDXrC2Rh8uJnujWMQGeyPszL1cuw8Ojes4exdIiIie1euVG8AXDiqvc8vCLjqHm0i6bLJJRtqnJ7HYQnmfLjp1ItgwzEiIi+pXLlwFAgIBbo+Ajy2Gxj6NtBxjEvlcViCIx9u2nBsvky97E3F85x6ISLyjsqVW2YDLYYa3udCeRyWYPDhplMvUSEBSL+Yjz+PnUcXTr0QEXl+5cplE83CXCSPwxKcdnFDAX4y9cKGY0REbu9yvrYLqYt1ILU3Bh9uakjbeHX9674UFBVXME9IRESupzAP2DYbmHkVsOWjSjZ2fAdSe2Pw4aa6NaqBaqEy9VKArUfPOXt3iIjIHIWXgK2fADPbA79M0a4mG1EbuGpkyQau0YHU3pjz4c5TLy3j8P32E/h8wzFVelsrIlg1HmPvDyIiFww6tn8BbHwPuJiqvU9GM3o8rg08AoKBJgNM9Pl41aUrV6zB4MONxUYGqeuVB9LURdSOCsbzw1piUOsypVdEROT4rqQFOVeCjpwz2vuiEoCek4D2dwP+2v/H3blyxRo+Go3GpRIGsrKyEBUVhczMTERGRjp7d1zW8n0peOjrneXu1w3YzbrnagYgRETO6kradzpwMQXYOBPITdfeX60e0HMy0O4uwD/Q4/42lpy/OfLhhiTBdPqS/UYf05QEIPJ4/5ZxnIIhInJGV9KFY6/crl4f6DkFaHcn4BfAvweDD/e07eh5pGSaqPcu+Wcgj8t2XRux/ToRkVO6ksp0ybCZQNs7GHSUwWoXN3QmO8+m2xERkR26kkqAUi2RgYcRDD7ckFS12HI7IiKy0NmDtu1e6mUsCj5mzJiBjh07IiIiArVq1cJNN92EQ4cOGWyTl5eH8ePHo0aNGggPD8fw4cORlsaDb0tSTitVLWWrwXXkfnlctiMiIhs6/w+w5DFg+VNe15XUacHH2rVrVWCxZcsW/P777ygsLMSAAQOQk5NTus3jjz+OJUuWYP78+Wr706dP45ZbbrHpTns76eMh5bTCVAAij7PfBxGRjaT9Bfz4APB+B2DHHKD4MuAX6FVdSV2m1Pbs2bNqBESCjF69eqnympo1a2LevHm49dZb1TYHDx5EixYtsHnzZnTp0qXS12SprWXltlLVop98Guzvi3fvbM8yWyIiWzjxJ7D+LeDvX6/c17i/tk9HTnpJtYvQP5WWfC108WXt3bbUVt5AREdrh/d37NihRkP69etXuk3z5s1Rr149k8FHfn6+uujvPJlHGolJOa1Utew6fgGvrzgEWeala6MYHkIiImsbg8l38n/+0AYdx9aXPMEHaHmjNuio3e7K60iA4SVdSW3J6uCjuLgYEydORPfu3dG6dWt1X2pqKgIDA1GtWjWDbWNjY9VjpvJIpk+fbu1ueD2ZWpFy2i4No/Fz0mkcSsvGh6uT0apOJNutExFZ0hhs4AzA118bdJwuaeIot6U/R/eJQEyT8q/lRV1JXSL4kNyPffv2YcOGDVXagWnTpmHSpEkGIx8JCQlVek1v5OPjgxa1I1Tw8en6f0rvZ7t1IiIzG4PNH3Xltn8wcPUooNsEoFol5yQJNBr05GG2d/DxyCOPYOnSpVi3bh3q1q1ben9cXBwKCgqQkZFhMPoh1S7ymDFBQUHqQlXP/1iUVL7mPDUzD+O+3sl260RE5jQGk+kVWeyty8NAeE0eM1eodpHcVAk8Fi5ciNWrV6NBgwYGj3fo0AEBAQFYtWpV6X1Sinv8+HF07drVdntNFrVbF/K4bEdE5LXMaQwm/2s26sPAw5VGPmSqRSpZfv75Z9XrQ5fHIdmtISEh6nrMmDFqGkWSUCXbdcKECSrwMKfShazDdutERGbIPGneYWJjMNcKPmbNmqWue/fubXD/F198gdGjR6uf33nnHfj6+qrmYlLFMnDgQHz00Ue23Gcqg+3WiYgqcDkf2Pkl8Mer5h0mNgZzreDDnJYgwcHB+PDDD9WFHIPt1omITAQdu74C1r8NZJ3S3ufjC2iKK2gMFs/GYA5QpT4f5Frt1iW51Fh4KO1u4thunYi8xeUCvaCjZKolojbQczIQUl3bqdRUYzDpz8EyWbtj8OFB7dalqkX++RgLQNhunYi8IuhI+kbbpyPzxJWgQ6pXpGw2oGSxTWmLzsZg7tte3R7YXt227daD/H3xHtutE5EndySVoGP3PGCdBB3HtfeFx2m7keoHHea+Hrl2e3Vy3Xbrf53OxMvLDiD/cjGaxVX8ISAicsuOpANeBvKzgfVvAhm6oCNWO9LRYTQQEGL6NdkYzKkYfHhou3W5bDpyDqsPnsHcTccwsFWcqoqR5FTJEeGKt0Tk9h1JF9x35XZYLW3Qcc19FQcd5BIYfHiwUd3qlwYfczYdK72fLdeJyGM6kkr1Sr/pQMcHgMBQR+4dOarDKbmXnPxCda0x0XJdckSIiNy6I6mUzcZfxcDDzTD48FDSSv2lpQeMPsaW60TkUqMbR9cDexdor+W2Trbx1dDLYUdSt8NpFw/FlutE5L5L278KBIUDa18z73XYkdTtMPjwUGy5TkTuu7S93K9jqntRyWPsSOqWOO3iodhynYjce2l7AJ0fAm54vyQAKelAWoodSd0Zgw8Pb7le9p+rjtwvj8t2RESut7Q9gOZDgatHArd/CUTWNnxMRjzk/pY32G03yX447eKh2HKdiFyWuQmiuu0kwGg+hB1JPQhHPjy84+mse65Wi8rpiwz2V/fL40REDnXxrDbfw9JEUl1H0ja3aq/ZCt2tceTDi1qu/7D9OBbuOo3YyGDV8ZSIyGHyMoFNHwBbPgIKLlayMRNJPR2DDy9qud4yPhIr/krD4TMX8fmGo4iJCGK7dSKyr8JLwLbZwIa3gUsXtPfVbg80GQCse91INQsTSb0Bgw8vEhUSgGsSq2Pd4XS8tOxKAzK2Wyciq5laHbaoENj1FbD2dSC7pJtyTFOgzzNAixsAHx8grg2XtvdSPhqNppJaJ9ddkpcsI+3UH/p6Z7n7dRUxzAMhoio3CYuoDbS6Gfh7OXD+H+19UQlA76eAtncCfmW+83Jpe49hyfmbIx9e1G59+pL9Rh/TlAQg8rjkh3DFWyKyukmYjHJIXocIjQF6PaFdadY/yPjrcGl7r8Tgw0uw3ToRObRJWFAk8OhOIDiKB57KYamtl2C7dSJyaJOw/CwgZQ8POhnF4MNLsN06EdnMGeMrZpfD1WbJBE67eFm79dTMPKMDpZLzIc3I2G6dyMtVlAAqpbIb3gG2zDLvtbjaLJnA4MNLsN06EVm9xH3/l7SJpOveBPIySv5TCQSKCky8EJuEUcU47eJFTLVbF88Na8F260TeTFe9UjaXQ27/OAb47Rlt4FGzBXDXD8At/+Nqs2Q1jnx4cbt1SUL9avO/2P7vBRxMqazdMRF5dfWKjx8w7F2g/d1XpmF8vmSTMLIKgw8vbrcu6lQLwa0fb8bCXacweUBT1IosPypCRB7OnOoVTRFQvYHhgm5cbZasxODDy11TPxpX16uGnccz8PIvB9CneS2u90LkbSxd4l4fm4SRFRh8kKpwkeDj56TT6iK43guRl5A1WI5vMW9bVq+QjTDh1MvJei8fry1Zf0GPlOSO+3qnepyI3Dyf4+h6YO8C7bXc1kleCczqBvw5u5IXkeqVOtqyWyIb4MiHF+N6L0ReWjrb/XHgyGrg71+194XW0K40u+MLLnFPrjnysW7dOgwbNgzx8fHw8fHBokWLDB4fPXq0ul//MmjQIFvuMzlhvRci8qDS2V+f0AYevv5Al/HAhJ3aSpbbvwIiaxtuL8HK7V9qk0uJnDXykZOTg3bt2uH+++/HLbfcYnQbCTa++EIiaK2gIBOrGZJTcb0XIi8unfULAv5vLVCrxZX7WL1Crhp8XH/99epSEQk24uLiqrJf5ABc74XIi0tni/KBnPTy97N6hdw14fSPP/5ArVq10KxZM4wbNw7nzp0zuW1+fj6ysrIMLuTY9V5kXRdTosMCkJqVh81HzqkcESLy8NJZIncMPmTK5csvv8SqVavw2muvYe3atWqkpKhIL8Naz4wZMxAVFVV6SUhIsPUuUSXrvQhTAcj5nEI8/n0SRszegh6vrWb1C5GrKy4GUnabty1LZ8lJfDQajdVfZyWZdOHChbjppptMbvPPP/+gUaNGWLlyJfr27Wt05EMuOjLyIQFIZmYmIiMjrd01soCU005fsr/C5FP9AEXWh5E27UTkYqvOnk4Clk0GTm2v5EVKFn6buNewYylRFcj5WwYRzDl/273UtmHDhoiJiUFycrLR4EPyQ5iQ6jrrvaRmXsJLyw7gfE751So1JQGIBCqyvYycEJELlM72eU4bcPz5mfZfamC4tnR29zyWzpJ3Nhk7efKkyvmoXZvflN1hvZe4qBCjgYcOy2+JXLB0dtFDwJ+yyqwGaH0r8Mh24OZZLJ0ll2XxyMfFixfVKIbO0aNHkZSUhOjoaHWZPn06hg8frqpdjhw5gqlTp6Jx48YYOHCgrfed7IDlt0RuWjorPTvu/hFo1PvKfSydJU8JPrZv347rrruu9PakSZPU9ahRozBr1izs2bMHc+fORUZGhmpENmDAALz00kucWnETLL8lctPS2eLLxvM3WDpLnhB89O7dGxXlqK5YsaKq+0QuUH4ra7uY+ivL47IdETkIS2fJw3BhObK4/FYeZ7IpkQOZW5TI0llyEww+yGj1i5TTxkUFGz061UMDVdOxn5NOsfkYkb2Xu9/wDrB4QiUbctVZ8qI+H86uEyb7ko6mUn4rSaiSC7Jw1yn8sP0E/H19cFmv26lMw8hoCHt/ENnQ8a3A0onAmf3a2zVbAGcPmC6d5eJv5Ebnb458UKXltze2r6OuOzeoru7XDzyE5IeM+3onu58SWVrBcnQ9sHeB9lpui9zzwOJHgc8HaAOPkGjgpo+BhzezdJY8ht2bjJHnjIK8+dvfRh9j8zEiGzQLi6gNtLxRG4zkliz4dtU9QP+XgNCSBG+WzpKHYPBBZpHpl4rar+s3H5NREiKqpFlY2Xqy7BRg68fan2OaAUPfAep3L/98ls6SB2DwQWZh8zEiBzULC4oE/m8tEBDCQ04eizkfZBY2HyNyULOw/CzgZGULwxG5NwYfZFHzsYqWkouNCESxRsMSXCJT2CyMSOG0C1nUfEyqWsoW+ulkXLqMu/+3tfQ2S3CJyig0nTdlgM3CyMNx5IOq3HwsNFC7nkT+5WKD+1mCS1SiuBjY9D6wTLsWlmlsFkbegSMfZHEA0r9lXGnzsZiwIEyevxu5BSU9CvSwBJcIwIV/gUUPA/9u0B6O2u2AlN2mm4UNetX4AnFEHoQjH1Sl5mO+vj5IzTKvBJfIq0jz6F1fA7O6awOPgDBg2HvAg2vZLIy8Hkc+qEpYgktkxMWzwJLHgEPLtLcTugA3zwKiG2pvs1kYeTkGH1QlLMElKuPAUm3gIV1KfQOAPk8D3R4tP5XCZmHkxRh8kE1KcCW51FTbpLjIILUdkUfLywR+fQrYPU97O7Y1cPMnQFxrZ+8ZkcthzgfZpARXmOoB0iwuUm1H5LGLwR1dp83tUIGHD9B9IjB2NQMPIhM48kE2K8GdvmS/wfov1UMDcCG3EGv/Povvth1HYo0wlSMiUzUyEsKAhDxiMTipXvl7ufZ29fraFWgTuzptN4ncgY9GIynZriMrKwtRUVHIzMxEZGSks3eHLFz5VleCqwswPlidjHdWll8Nlw3IyCMWg9N39Shg4MtAUIQj94zILc/fHPkgm5fg6msSG2Z0W10DMhkxkZETIrdeDC4kWrsKLftzEJmFOR9k15GQl5YeMPqY7r9xmaqR7YjcejG4S+e12xGRWRh8kN3IFIx+DkhZbEBGboGLwRHZHIMPshs2ICOPUJBr3nZcDI7IbMz5ILthAzJya5cLgA1vA+veMGMxuHggsZuDdozI/TH4IKc2IAsO8EWHxOr8K5DzkkklV0OmVmTkQgIISRqVhd8WjQfS9mq3q9MBOLWDi8ER2QiDD7J7AzKpaim7fqdOXmExpv20F2/c2lYtUkfk9L4dCZ2Bg0uB4svaKpbBbwCthwMHlpTfXkY8ZBVaWauFiMzGPh9kd8v3pZRrQCYjIkPb1sbnG4+papc7rknAf29qje3/XmAjMnKNvh0tbgCGvAWE16p8pISIYEmfDwYf5LQGZDIysnj3aUz8bhek2jY00A+5BSXtqtmIjOxFAoh3W1dcPisjHk8kM7AgslPwwWoXcmgDshvb11HXutbqN7SLx6hu9dXP+oGHfiMyGTkhshn27SByOgYf5PQRkeX7Uo0+xkZkZBfs20HkdAw+yKnYiIwcLjTGvO3Yt4PIdYKPdevWYdiwYYiPj4ePjw8WLVpk8LisU/fcc8+hdu3aCAkJQb9+/XD48GFb7jN5YSOy1MxL2HzkHH5OOqWu2ZKdrJJzDtj4jhl9O+qwbweRK5Xa5uTkoF27drj//vtxyy23lHv89ddfx8yZMzF37lw0aNAAzz77LAYOHIj9+/cjODjYVvtNXtaI7MWl+3Eht7D0NlfFJYud2qmtcMk8AfgFAkUF7NtB5CRVqnaRkY+FCxfipptuUrflpWREZPLkyZgyZYq6T7JeY2NjMWfOHNx55502zZYl9ycjGD1eW11hIzJjdB1BuCoumWXnl8CyKUBRPhDdELjja+DcESN9O+qwbweRlSw5f9u0ydjRo0eRmpqqplp0ZEc6d+6MzZs3Gw0+8vPz1UV/58l7mNOIzBjZTraX/iH9W8aVVs+Qlyvbh6PO1cDyp7TBh2g2GLj5YyA4CohtBTQfwr4dRE5g0+BDAg8hIx365LbusbJmzJiB6dOn23I3yM0Mal1bjWCUbUQWHRaA8zlXploqWhVXynfJyxnrWOobABTLZ8gH6PM00GMy4KuX6iYNwhr0dMruEnkzp7dXnzZtGiZNmmQw8pGQkODUfSLnBCAygqHfiCw1Kw+Pf59U6XNle1NNzMjLO5aqwANArye0FyLyvOAjLi5OXaelpalqFx253b59e6PPCQoKUhciXSMyHalqMcfBlGy8+uvqcu3bZTpHghrygqkWGfGoaNIu6Rug91PsWErkiX0+pLpFApBVq1YZjGRs3boVXbt2teVbkRetilvZ+MWstUcMAg/B7qhexJyOpVmntNsRkXuOfFy8eBHJyckGSaZJSUmIjo5GvXr1MHHiRPz3v/9FkyZNSkttpQJGVxFDZItkVN1tmVmRdWFMJaS+sPgvRAQHIP1ivtXTMa4ypVPV/XCV38Pm2LGUyPODj+3bt+O6664rva3L1xg1apQqp506darqBfLggw8iIyMDPXr0wPLly9njg2yajBoXFYw7OybgnZWmG9hJAJKalY+7/7fV6ukYUyvyWjqlU9UTf1X3w1a/h8tOu5iDHUuJXAZXtSW3YOzkvXTPaTz2XeUJqdb2B5ETtoy6aKrYY8QWgUNV9sNWv4dL+ncz8N1dwKXzlXQsjQcm7mXOB5En9vkgclQyqiXdUfXpTsDPLNqHOtVCDaou9RUXa7fRVLHHiKkTvy4npbITvwRd8j4aK38XW/0eLmnvAmDROG2n0uoNgAtH2bGUyE1w5IO8rjuqLbWpE4XGtcJRIywQMRFBiAmXS6C6jg4LxC0fbVRTP6bUigjCJyM74EJuAdKzC3D2Yr7KTzl3sUBdnzifixMXLtn99/h2bBf36ZUiTZnXvwms/q/2dvOhwC2zgeSV7FhK5CYjHww+yK3pRhaEpQFIZLA/ggP8jD6WV1iErLzLcBemfhdzf4/rW8dhXO9GaB0fBd8KRkCcnrR6uQBYOlFbOiu6PgL0f/HKdErZDqeJ3TjVQuQgDD7IqxjLqajqt33pMTJi9pZKX2PctY1QLVRbTZNeMlqhuz53Md9oJU5ZUSEBSIgOKRk1MRw9OZOdj1d+OWD172Lu76Ej73tt01ro07wWejSJUfvmMkmrlzKAH0YCR9cBPr7A4DeAjg/Y/32JyCzM+SCv7o4aExaEyfN3Iy3L+HSMT0m1jHxrr6zHiKkpHd1rTBnYzOQ3/43J6QaVNqZ8fE8Hk0GQjDR8sfFopfth6nep7PcQUSH+6NKwBjYmn1OB0487T6qL/F4dEqvjuma1EOjvg5eWlg+CzM1dqbILx4BvbgfSDwGB4cBtc4Am/e33fkTkPk3GiJydkHpj+zro3iQGL9zQUt1fNizQ3ZZv6xVNF+h6jFTlNeSEXlGTNLm/diVBUFX3o7Lny+W14W3xychrsPPZ/pj3QGeM7dlA5bHoplheW37QaOAhdAGNjIjI9nZxcjvwv37awCMiHrh/OQMPIjfH4IM8uj+IjArok9vmfkuv6mvYIoCxxX6Y+/xAf190axyDp4e0xMpJ12L91Ovw4o2t0D6hWoWvr7/An83t/xmYMwTIOQvEtQXGrgLi2tj+fYjIoZhwSh7NFgmSzm4QZqv9sPb5PyedMqufioyYPDGwuQpibFLRsul94PfntOFNk4HArZ8DQeFVf20isgsmnBK5GKdXiVSBJUmrUnVzfevaGNYuHl0aRsPfz4pApOgy8MsUYMcX2tsdxwKDXgX82JaIyJUx+CAih/ZTCQv0Q1iQv6rO0a+cGdxGG4h0qFe9fAmvsbLYghxgwX3anh0yOTVoBtBlHP+aRG6AwQcROaSfin6Ldqk4+vPYeSzefRq/7k3BhdzC0u3io4IxtF08hrWNR+s6kfA5sKR8QzAJQPwCgcwTQEAoMPx/QPMh/EsSuQkGH0Rkc5bkrhQWFatS4yW7U/DbX6nIzr/S6Kx+hAbDchdhmN8mNPU9Vf6NgqNQdM8ibMtPdMtpKiJvlcUOp0TkKrkr0mV17d9nsWT3aaw8kIa8wuLSx5r5HMf9fr/iVr918PPRjqnkBdVEX81HOJVV6Hkr8BJ5sCwLgg+W2hKRVf1U5Nqc0Qhp+z6wVRw+uOtq7BgZhvcC3kc/3+0IwGVEIhfX+21TgcffxXXw5eV+OJ9XhISLu402M5PRFyJyf0wfJyKHCcs/gxv9NqtLjiYIQSiEv08xthY3x5iCKbiIUDx3+X5EI8uzVuAlIgMc+SAix5Gk0hJhPvkq8BANfU5hqv/36OSj7aR6HpGObWZGRA7F4IOIHEfKaUPLr2NT0ycb9/r/ju8CX8KiwGfhgyt5IWW9vuIg5m8/gTNZli0kSESug9MuROQ4Z/YDhblGH9KoiRUNZl0eBk0F34t2Hc9QF9GidiSubVpTXWQRvIq6q7pzozciT8Pgg4gc4/xR4KtbgMJLQM1mQF4WkK2XQBoZj//k3o3f8tubfIkaYYG4s1M9rD98FntOZuJASpa6fLz2iGp0JmvT6IKRhOhQm7e4JyLb4NouRGR/2WnA5wOBC0eB2DbAfcuAwPByHU6X7z9TaTMzXbCQfjEfGw6n449DZ7D+cDrO5RQYvGWjmmG4tmkthAX54f3VyeV2ydhrEpH12OeDiFxHXqZ2ZdrUvUD1+sD9vwERVxJPy7JmlKK4WIO/Tmdh7d9n8Mehs9h1IkNNs1TGp2R13w1P9ql0CobTNkQVY/BBRK6hMA/4ejjw7wYgrCYw5jcgumGlT6vqiT7zUiE2Jafjh+0nsebQmUq3f+XmNhjeoQ6C/P2MPs5pG6LKMfggIufQXywuNAbY9ilwaBkQFAmMXgrUbufQ3fk56RQe+y7JrG0D/HzQuFYEWsVHllyi0DI+EhsOn1VTQWXHUThtQ2R98MGEUyKyjf2Lyy8WJ3wDgDvnOTzwEDJqYg7JC8nJLypNYF2w48pjMuJibAKHjc+IrMfgg4hsE3j8cG+ZNNESxYXApQtOOcoyXSP5ItKeXVNBzsf6qdchNStP5Y3IZf/pTOw7laXuqyh3RNf4bOGuU7j5qjoWTQ0xh4S8GatdiKjqUy3vti4/4nHlvxlVRouJewFf4zkV9iT5GuZW0JT1zZZ/8fSifWa9T3CAL5rFRaJl7Ug1XSPXzeMiEBbkX+UcEgYq5A447UJEjiM5HiYDD6EBsk5pt2vQE44mJ3MJMMqe7OPM6PPRsGa4We8R5O+rVuvdfSJDXXR8fIAGNcJUMzRdQJKadQnTfiof0OgWzysbDDHZlTwRp12IqGokudSW29mBnMxlQTpLK2jMnbZZ+8R1OHkhF/tTZMpGmzciP6dl5eOf9Bx1Wba34hV5da+vv3iebtRGY2agUhZHTMhVMfggIpstFmeT7exETuZdG9Ww+DkyOiInem3z9yt0YYs8Lm3dZZRELkPbxpduI43QJBCRPBK53vHvBZy8cKnC95TRmZs+3IjWdSKxdE+K1cmuHDEhV8acDyKqmoIc4LVEoKjQJXM+bMFWJ3JLSn/NdU/nRHRqGI3YiCDERgajVmQQ1v1tv/JgjqaQKcz5ICLH0GiApZMqDjzEoFfdNvCoyrSNtaW/D13bEEfTc7Dir8qnqr7e+q+66Cs7SqOju++FxX+ZHDGpCEdTyFZMLwFppRdeeAE+Pj4Gl+bNm9v6bYjIFWx8F9jzHeDjB/Saqh3h0Ce3b/8SaHmDs/bQ5tM2N7avo66tWRFXl0Ni6plyvzz+xMDmGN2tgVmv2a1RDXRuEI0GMWEICdAGeJU1lk/Nykeft/7A+G924s0Vh7Bgx0k1JXQ+pwAaCSiN0OWf6I/+6OefyONETs35aNWqFVauXHnlTfyZWkLkcR1ML/wLrH5Je//1rwGdxgK9nyq3WJw7j3jYmrk5JLKducmuX43pXBoISeDww/YTePLHvZXuy7/nctWlrMhgfzSoGY4GNULRICYc9WNCkVgjDM8v/ssuzdY4jeOd7BIVSLARFxdnj5cmIlfrYNqwD9DxAe3PEmg4oZzWnZhb+mtJoFJ6v48P6kWHmbUfUwY0U71JZHpHd5H9ycq7XK5kuDK6ZmsyLWVJUi+ncbyXXYKPw4cPIz4+HsHBwejatStmzJiBevXqGd02Pz9fXfQTVojIjTqY/rMaOLDEI6ZWXC2HxJoeJeaOmIzr3ajc+10qKMK/53Nw9Ky2PPiYXM7l4GBqNrLzLlf6e903ZxsSqoeq15d9iIsKKbkORnxUiLqWkRUJkqpaRqyPoyfux+bVLr/++isuXryIZs2aISUlBdOnT8epU6ewb98+REREGM0RkW3KMmdhGiJyABfvYOoNLD25VqWrqzGbj5zDiNlbYAuhgX6IiwxWJccFRcVGt9EFSBue7FPpNA67xboOl1rVNiMjA4mJiXj77bcxZswYs0Y+EhISGHwQuYqj64G5QyvfbtRSTrm4EFtOaUjw0+O11RWOpkiJ71f3d0Zadp7aTi4pWdrr0xmXkJaVhwu5pqqijOvROAZX16uGutGhqBcdioToUBW46AISU6MnpoIsTvN4UalttWrV0LRpUyQnJxt9PCgoSF2IyEW5QQdTsl95sLn5J9NvaIWmcRHqYkpeYZEKRhbsOIEP1hyp9H03JKeri74APx/EVwtR0zs7j18wOwmW0zyuxe7Bh0zBHDlyBCNHjrT3WxGRF3cwJdt0dbXHGjk6wQF+qB8Thu6Na5oVfIzomKAWyJHW9SfO5+JUxiUUFmlMVuoYS4Id/N561K0egk1H0m1SrWPt6AnzUuw87TJlyhQMGzZMTbWcPn0azz//PJKSkrB//37UrFnTpsM2ROQAmae0OR8a4/PzzPnwLrY4iZozjWMs50Oel5qVpwKRxUmnMG/bCdiS9Eu5ql51JNYIRWLJNI+Mslg7zWOr6Z4iGxxzj592OXnyJEaMGIFz586pYKNHjx7YsmWLWYEHVaHngn5PBVP3V/Y8orIu5wPzR1cceHhAB1Ny7GiKNWXEuufVqRaiLvK12ZzgY2LfJir35Ps/K99269Hz6lJ2mkemeCQQ+fPYeYtHT6o63bPchrk7roRru3hSzwWpOGh9K7BvQfn7B72mLYU09Tzd40T6ljwG7JgDBEUBfZ4BNr5T5rNTRxt48LNDVqjKidWS0RMZNTCnWmdkl0RI3PDv+VwcP5eLExdy1TSPJW5qH48OidXVOjs1I4Lwf1/twJnsK0UVpvbRz8TigLZao8cRoycuVe1iKU67VLHnglElH7BuE4BN7xt5XsnjHtIGm6xUdkTs1A5g5fPaz8fd84Em/TlqRjZXlZOiuSXFVZnmScm8pAKRn3efNmv0xBr3d6+PNnWjEBboj/Bgf4QH+auS5Ltmb7U6cHHG6AmDD1PDx+l/w+0VFwPfDAdyzlrxZFPLTZU8xl4N3stU91LR/0Wg+2PO2CuiSpl7Yq1q7xNze50MaKlNvJbSYukaKx1j7Wlkl0RcnVgNNcKCUCM8UF1HhwUi0N/X5qMnlWHwYUx6MvBBB5scYI828mft3D3zQbxHZSNpt30JtLrR0XtFZPPRE0dN8+je29yApWP96ipYuJhfhJz8y+pyIbcAeYWmcq0qJ51kJQjRVQhVdfTE7fp8uAxfXyDcA9abuXwJyMu03+svGA1cunDlNvNBPH+qRUY8KprCWzENaDGUCaXk9kmwVel9Yk2SrLmt7r97sGu5fTA3cJFVjX19fJB+MR/ncgrUysQSKMmIS2WjLtauyWML3hN8RDcEphyC13SbtJZ+4CGyUrTfipkP4pl5HVLFYrJteomsU9rncME48vJqHUt7nVhb1SOsWdVYFKvAoxDpFwvwc9IpvL/aeINPfRKIOZr3BB+eQspiZTRCggKzE05L+PjKmtsWPq+kiGz5U0DzIfz262l5HSHVzHsuu5cSWTV6Ym1zNj8rAxdfXx9UCw1Ul26NYswKPuR3cDQGH+5G8jGkLFbN0VeUQKqv5MPZ9ZGSahdzn6ej4bdfT83ruGTmsunsXkpk9eiJtdM9g6rYVdbc0RPZztEYfLgjKYeVaZBy/TrqAK2Hm+jzUdKLoW5HI99+q5efbjFm3ZuAXyCQ0Em1PDbAxmXunddhUkkVlIy4EZHDp3sGOThPxVHY58Od2arDqcz7f2lBf4/qDYC2dwBtbwdqNGLjMo/NE2L/FyJPsJx9PirHJmNOIMGIrN1RUR5JaA2gcX/gwBKgMOfK/TUaA+eMzSnyxOUy9i4AfhxT+XZlR8DYvZTIYxS5WIdTTrtQJXkkJR/Ooe9qp20K3gYOLgN2fwf8s8ZE4CGYqOoyzM3XuHUOe7wQeSg/G65wbAvaFmhEujySyDIJTDLfr19mGximnW4Z+ZP2ZGVuoio5j/wNKs3rqKMtpZVLm1u111wojojshCMfdIUEGFJOa+6Kt8WF5h09lmk6z7bZwC9PVLABV6UlIsdj8EGGJNAwt5mUucP5548a3mZljP1JP5f1bwKr/6u93en/tIGkdCs1VQlFROQgDD7I/g3P1vwXOL0LGPw6cGqnkRJhOQG+xhOgLQOP354BNn+gvX3tk0Dvadry6BbDzB/ZIiKyE5bako2aV8FIoqoGaD4M+PtXoPgy4B+kXV24/MdQe8UW7pYrO4qU0Bn4ZTKw80vt4wNnAF0ftuKFiYgsw2oXcoGGZ3rD+Wn7gaUTgRNbTbwIK2Ns1i7dP0S7+KC00r/hfeCqe6x7bSIiO+K0C9k/UTW2JXDd05U0MmMLd5u0S5fAQ3R5mIEHEbksBh/kmETVnLPmvQ4rY2zTLv2vhUD/F5nPQUQuiX0+yDHMrYzR305OstIaXDp0yrXcJu0Ik/5UizHsr0JELowjH+RalTGy6m5EbeDMflbFVHV0iKNIROSiOPJBjm3hrphYT8DHDzi8AvioE/DDyPLf7iVwkTwHyXfwZtaMIhERuRAGH+QCLdzrALd/BTy8Rbt4ncnplZIRk+VPefcUjIwihcZU3i5dtiMickGcdiHXqozp/hiQ/HsFL8CqGJW8K31TjGK7dCJyfQw+yLUqY5jPULHLBcAPo4C8DO3ohqYIyE698jjbpRORG2DwQa6F+QwV++1p4MQWICgSuHcxEN2A7dKJyO0w+CA3rIrxATKOa9cwkfVKvEXSt8C2T7U/3/IpENNY+7O5CwESEbkIJpyS+1XFSFDy88PAgvuASxfgFU4naVvU6xaKa3a9s/eIiMhqDD7Ivapibp0L9HkG8PXXdvGc1R34Zy08Wu554PuRwOU8oMkA4NqnnL1HRERVwlVtyX1WbNWvijm1A/hxLHD+iHaEpNsjQJ9ntSvnetox+Ho48M8aoHoD4ME1QEh1Z+8VEVGVVrVl8EHuqyAHWPEfYMcc7e3YNsDw2UCtFhUHLuaq6mtY8/yyz0leCWx8FwgIBR5YCcS2sux3ICJyweDDbgmnH374Id544w2kpqaiXbt2eP/999GpUyd7vR15o8AwYNh72qmIxROAtL3Ap72BNrdpT9rZkrSqX4L6mnZKx9rl6i15DWueb+w5Oje8z8CDiDyGXXI+vv/+e0yaNAnPP/88du7cqYKPgQMH4syZM/Z4O/J20rRs3GagcT9tXsSurwwDD0tbs+uWq7e2vbs1zzf1HB2/wMr3m4jIm4OPt99+G2PHjsV9992Hli1b4uOPP0ZoaCg+//xze7wdERARC4z4HgiOMnE0pGxXA/wyBbh4Bii8pC3VtWi5ejPau1vz/AqfI3zYUp6IPIrNp10KCgqwY8cOTJs2rfQ+X19f9OvXD5s3by63fX5+vrrozxkRWeX4ZiAvs+JtJJfizSban318tbkUcgmU6zBAc7mS5epL2rvPH62tvilLHrP0+eY+R3JB2NODiDyAzYOP9PR0FBUVITbWcEVNuX3w4MFy28+YMQPTp0+39W6QN7J0CXlNMVBwUXvJsfC9DlRxZV1rnm/p70dE5KKc3uFURkgkP0R/5CMhIcGp+0Qe3pp95M9AnauBwlxtxYy6zgUKc4CT24E1L1f+Gm1uB6oZ+ZxmnAD2/mDZ8819jrm/HxGRtwUfMTEx8PPzQ1qa4bc0uR0XF1du+6CgIHUhsn9rdllqPl47dSElr8FGSsEaXAvs+KLy17j5Y+Nls6pUdoNlzzf3OfL7ERF5AJsnnAYGBqJDhw5YtWpV6X3FxcXqdteuXW39dkRmtmY3c6n5qr6GNc+3xX4TEXl7tYtMo8yePRtz587FgQMHMG7cOOTk5KjqFyLntGaP195vTo+Oqr6GNc+3xX4TEbkJu3U4/eCDD0qbjLVv3x4zZ85E586dbdohjcgkT+lwas1+ExE5AdurExERkcsGH1zVloiIiByKwQcRERE5FIMPIiIicigGH0RERORQDD6IiIjIoRh8EBERkUMx+CAiIiKHYvBBREREDD6IiIjIc9l8Vduq0nV7l05pRERE5B50521zVm1xueAjOztbXSckJDh7V4iIiMiK87i0WXfKwnLWKi4uxunTpxEREQEfn7LLi1c9KpOg5sSJE1y0zo54nB2Dx5nH2ZPw8+z+x1nCCQk84uPj4evr614jH7LDdevWtet7yAHnirn2x+PsGDzOPM6ehJ9n9z7OlY146LDahYiIiByKwQcRERE5lFcFH0FBQXj++efVNfE4uzt+nnmcPQk/z951nF0u4ZSIiIg8m1eNfBAREZHzMfggIiIih2LwQURERA7F4IOIiIgcymuCjw8//BD169dHcHAwOnfujG3btjl7lzzOCy+8oLrS6l+aN2/u7N1ye+vWrcOwYcNU10A5posWLTJ4XHLGn3vuOdSuXRshISHo168fDh8+7LT99dTjPHr06HKf70GDBjltf93VjBkz0LFjR9XFulatWrjppptw6NAhg23y8vIwfvx41KhRA+Hh4Rg+fDjS0tKcts+eepx79+5d7jP90EMPOWT/vCL4+P777zFp0iRVXrRz5060a9cOAwcOxJkzZ5y9ax6nVatWSElJKb1s2LDB2bvk9nJyctRnVgJoY15//XXMnDkTH3/8MbZu3YqwsDD1+Zb/wMl2x1lIsKH/+f722295iC20du1aFVhs2bIFv//+OwoLCzFgwAB1/HUef/xxLFmyBPPnz1fby5Ibt9xyC4+1jY+zGDt2rMFnWv4/cQiNF+jUqZNm/PjxpbeLioo08fHxmhkzZjh1vzzN888/r2nXrp2zd8OjyT/ZhQsXlt4uLi7WxMXFad54443S+zIyMjRBQUGab7/91kl76XnHWYwaNUpz4403Om2fPNWZM2fU8V67dm3p5zcgIEAzf/780m0OHDigttm8ebMT99SzjrO49tprNY899pjGGTx+5KOgoAA7duxQQ9H668fI7c2bNzt13zyRDPfLsHXDhg1x99134/jx487eJY929OhRpKamGny+ZW0FmVrk59v2/vjjDzWE3axZM4wbNw7nzp2zw7t4l8zMTHUdHR2truX/a/mWrv+ZlunbevXq8TNtw+Os88033yAmJgatW7fGtGnTkJubC0dwuYXlbC09PR1FRUWIjY01uF9uHzx40Gn75YnkhDdnzhz1H7MM302fPh09e/bEvn371Lwj2Z4EHsLY51v3GNmGTLnI0H+DBg1w5MgR/Oc//8H111+vToh+fn48zFauYj5x4kR0795dnfyEfG4DAwNRrVo1g235mbbtcRZ33XUXEhMT1RfGPXv24Mknn1R5IT/99BPszeODD3Ic+Y9Yp23btioYkQ/2Dz/8gDFjxvBPQW7tzjvvLP25TZs26jPeqFEjNRrSt29fp+6bu5KcBPlywtww5xznBx980OAzLUnr8lmW4Fo+2/bk8dMuMpwk30rKZkrL7bi4OKftlzeQby5NmzZFcnKys3fFY+k+w/x8O55MLcr/L/x8W+eRRx7B0qVLsWbNGtStW9fgMy3T5RkZGQbb8/9s2x5nY+QLo3DEZ9rjgw8ZvuvQoQNWrVplMAQlt7t27erUffN0Fy9eVBG0RNNkHzIFIP9Z63++s7KyVNULP9/2dfLkSZXzwc+3ZSSfV06ICxcuxOrVq9VnWJ/8fx0QEGDwmZapAMkf42fadsfZmKSkJHXtiM+0V0y7SJntqFGjcM0116BTp0549913VbnRfffd5+xd8yhTpkxRfRJkqkVK46S0WUadRowY4exdc/sgTv+biCSZyn8SkjgmSXgyl/vf//4XTZo0Uf/BPPvss2oOV+r6yTbHWS6SwyT9JiTYk6B66tSpaNy4sSprJsumAObNm4eff/5Z5YLpcpMkUVr61Mi1TNPK/9ty3CMjIzFhwgQVeHTp0oWH2kbHWT7D8vjgwYNVPxXJ+ZAS5169eqkpRbvTeIn3339fU69ePU1gYKAqvd2yZYuzd8nj3HHHHZratWurY1ynTh11Ozk52dm75fbWrFmjSuTKXqT0U1du++yzz2piY2NViW3fvn01hw4dcvZue9Rxzs3N1QwYMEBTs2ZNVQaamJioGTt2rCY1NdXZu+12jB1juXzxxRel21y6dEnz8MMPa6pXr64JDQ3V3HzzzZqUlBSn7renHefjx49revXqpYmOjlb/bzRu3FjzxBNPaDIzMx2yfz4lO0lERETkEB6f80FERESuhcEHERERORSDDyIiInIoBh9ERETkUAw+iIiIyKEYfBAREZFDMfggIiIih2LwQURERA7F4IOIiIgcisEHERERORSDDyIiInIoBh9EREQER/p/suaYral7JoEAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "tsr_15mw_csv = \"/Users/sky/src/HowlandLab/MITRotor/MITRotor/FlorisInterface/tsr_15mw.csv\"\n", + "pitch_15mw_csv = \"/Users/sky/src/HowlandLab/MITRotor/MITRotor/FlorisInterface/pitch_15mw.csv\"\n", + "check_interp(tsr_15mw_csv, pitch_15mw_csv)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "51835dd1", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "tsr_15mw_csv = \"/Users/sky/src/HowlandLab/MITRotor/MITRotor/FlorisInterface/tsr_5mw.csv\"\n", + "pitch_15mw_csv = \"/Users/sky/src/HowlandLab/MITRotor/MITRotor/FlorisInterface/pitch_5mw.csv\"\n", + "check_interp(tsr_15mw_csv, pitch_15mw_csv)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a2cdf23d", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "mitrotor-l4Gn_-ln-py3.12", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.11" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From ad926ef68eb9fa7cb3847c7ba86ed60bbcae2cb7 Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Mon, 5 Jan 2026 15:31:37 -0500 Subject: [PATCH 03/19] Working attempt, but power values uncertian --- MITRotor/FlorisInterface/FlorisInterface.py | 140 +- MITRotor/Geometry.py | 4 +- examples/example_05_floris_integration.ipynb | 145 +- examples/example_05_floris_integration.py | 35 + poetry.lock | 2015 ++++++++++-------- pyproject.toml | 2 +- 6 files changed, 1394 insertions(+), 947 deletions(-) create mode 100644 examples/example_05_floris_integration.py diff --git a/MITRotor/FlorisInterface/FlorisInterface.py b/MITRotor/FlorisInterface/FlorisInterface.py index b04e131..d4285fa 100644 --- a/MITRotor/FlorisInterface/FlorisInterface.py +++ b/MITRotor/FlorisInterface/FlorisInterface.py @@ -1,16 +1,25 @@ import numpy as np +import os from attrs import define, field from typing import Literal, Optional from scipy.interpolate import interp1d # FLORIS Imports from floris.type_dec import floris_float_type, NDArrayFloat from floris.core.turbine.operation_models import BaseOperationModel -from floris.core.rotor_velocity import average_velocity -# MITRotor Imports +from floris.core.rotor_velocity import average_velocity, rotor_velocity_air_density_correction +# MITRotor / UMM Imports from MITRotor.ReferenceTurbines import IEA15MW from MITRotor.Momentum import UnifiedMomentum from MITRotor.Geometry import BEMGeometry -from MITRotor.BEMSolver import BEM, BEMSolution +from MITRotor.BEMSolver import BEM +from UnifiedMomentumModel.Utilities.Geometry import calc_eff_yaw + +def default_bem_factory(): + return BEM( + rotor=IEA15MW(), + momentum_model=UnifiedMomentum(averaging="rotor"), + geometry=BEMGeometry(Nr=10, Ntheta=20), + ) def csv_to_interp(csv_file): # read in csv @@ -23,7 +32,7 @@ def csv_to_interp(csv_file): x = x[idx] y = y[idx] # return interpolator for y - return interp1d(x, y, kind="linear", bounds_error=False, fill_value="extrapolate") + return interp1d(x, y, kind="linear", fill_value=0.0001, bounds_error=False) @define class MITRotorTurbine(BaseOperationModel): @@ -31,71 +40,100 @@ class MITRotorTurbine(BaseOperationModel): A turbine operation model that calls MITRotor. """ # user can define a BEM model if they want a different rotor, momentum model, or geometry - default_bem = BEM( - rotor=IEA15MW(), - momentum_model = UnifiedMomentum(averaging = "rotor"), - geometry = BEMGeometry(Nr = 10, Ntheta = 20), - ) - bem_model = field(init = False, default = default_bem, type = BEM) + bem_model = field(init = True, factory = default_bem_factory, type = BEM) # save most recent solution by unique floris arguments - _bem_sol = field(init=False, default=None, type = Optional[list[BEMSolution]]) - _avg_vels = field(init=False, default=None, type = Optional[NDArrayFloat]) _last_key = field(init=False, default=None, type = bytes) - # save blade pitch and tsr interpolation objects - # TODO -> figure out how to make csv change with rotor type - _pitch_interp = field(init = False, default = csv_to_interp("pitch_15mw.csv")) - _tsr_interp = field(init = False, default= csv_to_interp("tsr_15mw.csv")) + _a = field(init=False, default=None, type = NDArrayFloat) + _Ct = field(init=False, default=None, type = NDArrayFloat) + _power = field(init=False, default=None, type = NDArrayFloat) + # user can define csv paths for pitch and tsr values + module_dir = os.path.dirname(__file__) + default_pitch_csv = os.path.join(module_dir, "pitch_15mw.csv") + default_tsr_csv = os.path.join(module_dir, "tsr_15mw.csv") + pitch_csv = field(init = True, default = default_pitch_csv, type = str) + tsr_csv = field(init = True, default= default_tsr_csv, type = str) + # create interp objects based on pitch and tsr csvs + _pitch_interp = field(init=False, default=None, type = interp1d, repr = False) + _tsr_interp = field(init=False, default=None, type = interp1d, repr = False) - def _get_solution_key(self, velocities: np.ndarray) -> bytes: # TODO: add more inputs + def __attrs_post_init__(self): + self._pitch_interp = csv_to_interp(self.pitch_csv) + self._tsr_interp = csv_to_interp(self.tsr_csv) + + def _get_state_key(self, velocities: np.ndarray, yaw_angles: np.ndarray, tilt_angles: np.ndarray) -> tuple: # Fast, deterministic, and explicit - return velocities.tobytes() + return velocities.tobytes(), yaw_angles.tobytes(), tilt_angles.tobytes() - def _get_solutions(self, + def _update_solution(self, + power_thrust_table: dict, velocities: NDArrayFloat, + air_density: float, yaw_angles: NDArrayFloat, tilt_angles: NDArrayFloat, + average_method: str = "cubic-mean", + cubature_weights: NDArrayFloat | None = None, + **kwargs, ): n_findex, n_turbines = yaw_angles.shape # create cache key for current inputs - key = self._get_solution_key(velocities) # TODO: add more inputs + key = self._get_state_key(velocities, yaw_angles, tilt_angles) # TODO: add more inputs # update solution if conditions are different if key != self._last_key: - self._bem_sol = [None] * n_findex - self._avg_vels = np.empty((n_findex, n_turbines), dtype=velocities.dtype) + # save new key and clear fields self._last_key = key + self._a = np.empty((n_findex, n_turbines), dtype=floris_float_type) + self._Ct = np.empty((n_findex, n_turbines), dtype=floris_float_type) + self._power = np.empty((n_findex, n_turbines), dtype=floris_float_type) + + # compute the power-effective wind speed across the rotor + rotor_average_velocities = average_velocity( + velocities=velocities, + method=average_method, + cubature_weights=cubature_weights, + ) + # update effective velocities for air density + rotor_effective_velocities = rotor_velocity_air_density_correction( + velocities=rotor_average_velocities, + air_density=air_density, + ref_air_density=power_thrust_table["ref_air_density"] + ) # loop over flow conditions for findex in range(n_findex): - cond_vels, cond_yaws, cond_tilts = velocities[findex], yaw_angles[findex], tilt_angles[findex] - rotor_avg_vels = average_velocity(cond_vels, method="cubic-mean") # TODO: does method need to be user input? - pitch_vals = self._pitch_interp(rotor_avg_vels) - tsr_vals = self._tsr_interp(rotor_avg_vels) - self._bem_sol[findex] = self.bem_model(pitch_vals, tsr_vals, yaw = cond_yaws, tilt = cond_tilts) - self._avg_vels[findex] = rotor_avg_vels + for tindex in range(n_turbines): + vel = rotor_effective_velocities[findex, tindex] + yaw, tilt = np.deg2rad(yaw_angles[findex, tindex]), np.deg2rad(tilt_angles[findex, tindex]) + pitch_val = np.deg2rad(self._pitch_interp(vel)) + tsr_val = self._tsr_interp(vel) + bem_sol = self.bem_model(pitch_val, tsr_val, yaw = yaw, tilt = tilt) + self._a[findex, tindex] = bem_sol.a() + self._Ct[findex, tindex] = bem_sol.Ct() + # calculate power + rotor_area = np.pi * self.bem_model.rotor.R**2 + rotor_uinfty = vel * np.cos(calc_eff_yaw(yaw, tilt)) - return self._bem_sol - - def power(self, - velocities: NDArrayFloat, - yaw_angles: NDArrayFloat, - tilt_angles: NDArrayFloat, - **_ - ) -> NDArrayFloat: - return self._get_solutions(velocities, yaw_angles, tilt_angles).Cp() # TODO: what type of averaging do we want? AND make into POWER + # Construct power interpolant + power_interpolator = interp1d( + power_thrust_table["wind_speed"], + power_thrust_table["power"], + fill_value=0.0, + bounds_error=False, + ) + # Compute power + power = power_interpolator(rotor_uinfty) * 1e3 # --> I am not sure the rotor_uinfty is the right value... + self._power[findex, tindex] = power # it seems like using Cp (below) should be correct... plot power interpolator... + # self._power[findex, tindex] = 0.5 * bem_sol.Cp() * air_density * rotor_area * (rotor_uinfty)**3 - def thrust_coefficient(self, - velocities: NDArrayFloat, - yaw_angles: NDArrayFloat, - tilt_angles: NDArrayFloat, - **_ - ) -> NDArrayFloat: - return self._get_solutions(velocities, yaw_angles, tilt_angles).Ct() # TODO: what type of averaging do we want? + return + + def power(self, **kwargs) -> NDArrayFloat: + self._update_solution(**kwargs) + return self._power + def thrust_coefficient(self, **kwargs) -> NDArrayFloat: + self._update_solution(**kwargs) + return self._Ct - def axial_induction(self, - velocities: NDArrayFloat, - yaw_angles: NDArrayFloat, - tilt_angles: NDArrayFloat, - **_ - ) -> NDArrayFloat: - return self._get_solutions(velocities, yaw_angles, tilt_angles).a() # TODO: what type of averaging do we want? \ No newline at end of file + def axial_induction(self, **kwargs) -> NDArrayFloat: + self._update_solution(**kwargs) + return self._a \ No newline at end of file diff --git a/MITRotor/Geometry.py b/MITRotor/Geometry.py index 09cac9d..2e812ba 100644 --- a/MITRotor/Geometry.py +++ b/MITRotor/Geometry.py @@ -42,12 +42,12 @@ def cartesian(self, yaw: float, tilt: float) -> Tuple[ArrayLike, ...]: return X, Y, Z def annulus_average(self, X: ArrayLike): - X_azim = 1 / (2 * np.pi) * np.trapz(X, self.theta_mesh, axis=-1) + X_azim = 1 / (2 * np.pi) * np.trapezoid(X, self.theta_mesh, axis=-1) return X_azim def rotor_average(self, X: ArrayLike): # Takes annulus average quantities and performs rotor average - X_rotor = 2 * np.trapz(X * self.mu, self.mu) + X_rotor = 2 * np.trapezoid(X * self.mu, self.mu) return X_rotor diff --git a/examples/example_05_floris_integration.ipynb b/examples/example_05_floris_integration.ipynb index 5cafc1b..9552036 100644 --- a/examples/example_05_floris_integration.ipynb +++ b/examples/example_05_floris_integration.ipynb @@ -2,19 +2,20 @@ "cells": [ { "cell_type": "code", - "execution_count": 26, + "execution_count": 7, "id": "eb249327", "metadata": {}, "outputs": [], "source": [ - "from MITRotor.FlorisInterface.FlorisInterface import csv_to_interp\n", + "from MITRotor.FlorisInterface.FlorisInterface import csv_to_interp, MITRotorTurbine\n", + "from floris import FlorisModel, TimeSeries\n", "import numpy as np\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 8, "id": "9cc53ad8", "metadata": {}, "outputs": [], @@ -40,7 +41,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 9, "id": "08c83a7f", "metadata": {}, "outputs": [ @@ -53,7 +54,7 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAGdCAYAAACyzRGfAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjcsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvTLEjVAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAXh5JREFUeJzt3Qd4k2XXB/B/926hFFoKpey9FNlDZMtw4UJFUMRPRBQBUV4n+irugQOVVwUHDlCQoaAM2UNGGTKkCLLaQoEOWjpo813nTlOSNmmTNDv/33XlSpM8SZ4+DTwn933OuX00Go0GRERERA7i66g3IiIiImLwQURERA7HkQ8iIiJyKAYfRERE5FAMPoiIiMihGHwQERGRQzH4ICIiIodi8EFEREQO5Q8XU1xcjNOnTyMiIgI+Pj7O3h0iIiIyg/Qszc7ORnx8PHx9fd0r+JDAIyEhwdm7QURERFY4ceIE6tat617Bh4x46HY+MjLS2btDREREZsjKylKDB7rzuFsFH7qpFgk8GHwQERG5F3NSJphwSkRERA7F4IOIiIgcisEHEREROZTL5XwQEXlDSeLly5dRVFTk7F0hskhAQAD8/PxQVQw+iIgcqKCgACkpKcjNzeVxJ7dMJpUy2vDw8Cq9DoMPIiIHNlE8evSo+uYojZgCAwPZTJHcasTu7NmzOHnyJJo0aVKlERAGH0REDhz1kABEeiGEhobyuJPbqVmzJo4dO4bCwsIqBR9MOCUicrDKWk8TuSpbLXvCfwFERETkUFUKPl599VUVBU2cOLH0vry8PIwfPx41atRQCSnDhw9HWlqaLfaViIjIbY0ePRo33XSTy7yOWwYff/75Jz755BO0bdvW4P7HH38cS5Yswfz587F27Vq1UNwtt9xii30lIiInkC+ZFV1eeOEFtd3ChQvRpUsXREVFqfU9WrVqZfDldM6cOaXPkamn2rVr44477sDx48crfH95XrVq1Sza5969exu8tzs6duyYOlZJSUkG97/33nvqmHhd8HHx4kXcfffdmD17NqpXr156f2ZmJj777DO8/fbb6NOnDzp06IAvvvgCmzZtwpYtW2y530RE5CBSGqy7vPvuu2rdLf37pkyZglWrVqlAQka7t23bhh07duDll19WiYn6dM89deoUfvzxRxw6dAi33XabSycJu5qoqCiLgzGPCD5kWmXIkCHo16+fwf3yYZMPmv79zZs3R7169bB582ajr5Wfn69WwtO/2ENqZh7eW3kYr/560C6vT0TkqeLi4kovcuKTb+P698kUu4x4d+/eHU888QSaNWuGpk2bqqmBDz/80OC1dM+VUY9u3bphzJgxKlix5P9+GWlp3749vvrqK9SvX1/t05133ons7OzSaQkZeZcRAt1Ii4wiiH379uH6669X+xwbG4uRI0ciPT3dYMTkkUceUaMmMTExGDhwYOl+z5o1Sz03JCQEDRs2xIIFCwz2a+/eveqLtzwuqQcPPvig+rJuyvLly9GjRw8VSMj2Q4cOxZEjR0ofb9Cggbq+6qqr1PvLvhmbdpHz6KOPPopatWohODhYvabMTuj88ccf6vkSIF5zzTWq0kqOvQR+bhN8fPfdd9i5cydmzJhR7rHU1FRVt142IpM/sDxmjLyOfHB0FylBs4ez2fl4Z+XfmLvpGHILLtvlPYiIrOmdIP8nOfoi72tLElD89ddf6uRurjNnzqipGinZtLRsU07SixYtwtKlS9VFgg3JQxQSdHTt2hVjx44tHZ2Rc0tGRoYKDuRkvn37dnXyl5zE22+/3eC1586dq85lGzduxMcff1x6/7PPPqtGdnbv3q1G/yXgOXDggHosJydHBSoyGyAnfkk9WLlypQpkTMnJycGkSZPUvkhgIFNRN998syrHFhKUCXkd+R1++ukno68zdepUNYok+y3n58aNG6t9OX/+vMF2Tz/9NN566y31fv7+/rj//vvhLBb1+Thx4gQee+wx/P777yq6soVp06apg68j0a89ApDWdSKREB2CE+cvYc3BsxjStrbN34OIyFKXCovQ8rkVDj9w+18ciNBA27V6mjBhAtavX482bdogMTFR5X4MGDBAnaSDgoIMpudl1EEFXSVdXuVbe1hYmEXvJydoyXuQ3BIhIxhyApepHvkiK8GDfMOXoEjngw8+UIHHK6+8Unrf559/rs45f//9txqtEdJA6/XXXy/3njI99MADD6ifX3rpJXUufP/99/HRRx9h3rx5quDiyy+/LP1d5P2GDRuG1157TX0JL2v48OEGt2VfpI/G/v370bp1a/WzkFER/d+jbAAjIzJyLGRURkhKhOybpEHISJSOHJtrr71W/fzUU0+pGQzZZ1udz+028iHTKhKpXn311SpqkotEmzNnzlQ/y8GV+TGJLvVJ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iIjIc9l8Vduq0nV7l05pRERE5B50521zVm1xueAjOztbXSckJDh7V4iIiMiK87i0WXfKwnLWKi4uxunTpxEREQEfn7LLi1c9KpOg5sSJE1y0zo54nB2Dx5nH2ZPw8+z+x1nCCQk84uPj4evr614jH7LDdevWtet7yAHnirn2x+PsGDzOPM6ehJ9n9z7OlY146LDahYiIiByKwQcRERE5lFcFH0FBQXj++efVNfE4uzt+nnmcPQk/z951nF0u4ZSIiIg8m1eNfBAREZHzMfggIiIih2LwQURERA7F4IOIiIgcymuCjw8//BD169dHcHAwOnfujG3btjl7lzzOCy+8oLrS6l+aN2/u7N1ye+vWrcOwYcNU10A5posWLTJ4XHLGn3vuOdSuXRshISHo168fDh8+7LT99dTjPHr06HKf70GDBjltf93VjBkz0LFjR9XFulatWrjppptw6NAhg23y8vIwfvx41KhRA+Hh4Rg+fDjS0tKcts+eepx79+5d7jP90EMPOWT/vCL4+P777zFp0iRVXrRz5060a9cOAwcOxJkzZ5y9ax6nVatWSElJKb1s2LDB2bvk9nJyctRnVgJoY15//XXMnDkTH3/8MbZu3YqwsDD1+Zb/wMl2x1lIsKH/+f722295iC20du1aFVhs2bIFv//+OwoLCzFgwAB1/HUef/xxLFmyBPPnz1fby5Ibt9xyC4+1jY+zGDt2rMFnWv4/cQiNF+jUqZNm/PjxpbeLioo08fHxmhkzZjh1vzzN888/r2nXrp2zd8OjyT/ZhQsXlt4uLi7WxMXFad54443S+zIyMjRBQUGab7/91kl76XnHWYwaNUpz4403Om2fPNWZM2fU8V67dm3p5zcgIEAzf/780m0OHDigttm8ebMT99SzjrO49tprNY899pjGGTx+5KOgoAA7duxQQ9H668fI7c2bNzt13zyRDPfLsHXDhg1x99134/jx487eJY929OhRpKamGny+ZW0FmVrk59v2/vjjDzWE3axZM4wbNw7nzp2zw7t4l8zMTHUdHR2truX/a/mWrv+ZlunbevXq8TNtw+Os88033yAmJgatW7fGtGnTkJubC0dwuYXlbC09PR1FRUWIjY01uF9uHzx40Gn75YnkhDdnzhz1H7MM302fPh09e/bEvn371Lwj2Z4EHsLY51v3GNmGTLnI0H+DBg1w5MgR/Oc//8H111+vToh+fn48zFauYj5x4kR0795dnfyEfG4DAwNRrVo1g235mbbtcRZ33XUXEhMT1RfGPXv24Mknn1R5IT/99BPszeODD3Ic+Y9Yp23btioYkQ/2Dz/8gDFjxvBPQW7tzjvvLP25TZs26jPeqFEjNRrSt29fp+6bu5KcBPlywtww5xznBx980OAzLUnr8lmW4Fo+2/bk8dMuMpwk30rKZkrL7bi4OKftlzeQby5NmzZFcnKys3fFY+k+w/x8O55MLcr/L/x8W+eRRx7B0qVLsWbNGtStW9fgMy3T5RkZGQbb8/9s2x5nY+QLo3DEZ9rjgw8ZvuvQoQNWrVplMAQlt7t27erUffN0Fy9eVBG0RNNkHzIFIP9Z63++s7KyVNULP9/2dfLkSZXzwc+3ZSSfV06ICxcuxOrVq9VnWJ/8fx0QEGDwmZapAMkf42fadsfZmKSkJHXtiM+0V0y7SJntqFGjcM0116BTp0549913VbnRfffd5+xd8yhTpkxRfRJkqkVK46S0WUadRowY4exdc/sgTv+biCSZyn8SkjgmSXgyl/vf//4XTZo0Uf/BPPvss2oOV+r6yTbHWS6SwyT9JiTYk6B66tSpaNy4sSprJsumAObNm4eff/5Z5YLpcpMkUVr61Mi1TNPK/9ty3CMjIzFhwgQVeHTp0oWH2kbHWT7D8vjgwYNVPxXJ+ZAS5169eqkpRbvTeIn3339fU69ePU1gYKAqvd2yZYuzd8nj3HHHHZratWurY1ynTh11Ozk52dm75fbWrFmjSuTKXqT0U1du++yzz2piY2NViW3fvn01hw4dcvZue9Rxzs3N1QwYMEBTs2ZNVQaamJioGTt2rCY1NdXZu+12jB1juXzxxRel21y6dEnz8MMPa6pXr64JDQ3V3HzzzZqUlBSn7renHefjx49revXqpYmOjlb/bzRu3FjzxBNPaDIzMx2yfz4lO0lERETkEB6f80FERESuhcEHERERORSDDyIiInIoBh9ERETkUAw+iIiIyKEYfBAREZFDMfggIiIih2LwQURERA7F4IOIiIgcisEHERERORSDDyIiInIoBh9EREQER/p/suaYral7JoEAAAAASUVORK5CYII=", + "image/png": "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", "text/plain": [ "
" ] @@ -70,13 +71,20 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 10, "id": "51835dd1", "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] @@ -91,10 +99,131 @@ "check_interp(tsr_15mw_csv, pitch_15mw_csv)" ] }, + { + "cell_type": "code", + "execution_count": 11, + "id": "2a93558a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Powers [W]:\n", + " [[1753954.45917917 354990.76412771]\n", + " [3417797.00509157 737171.66537995]\n", + " [5000000. 4927707.14320011]] \n", + "\n", + "Thrust coefficients [-]:\n", + " [[0.78715145 0.9353766 ]\n", + " [0.78387889 0.86092059]\n", + " [0.55092883 0.74517368]] \n", + "\n", + "Axial induction factors [-]:\n", + " [[0.26932244 0.37289433]\n", + " [0.26755586 0.31353324]\n", + " [0.16493614 0.24759837]] \n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/sky/Library/Caches/pypoetry/virtualenvs/mitrotor-l4Gn_-ln-py3.12/lib/python3.12/site-packages/floris/core/flow_field.py:172: UserWarning: 'where' used without 'out', expect unitialized memory in output. If this is intentional, use out=None.\n", + " * np.power(\n" + ] + } + ], + "source": [ + "from floris.core.turbine.unified_momentum_model import UnifiedMomentumModelTurbine\n", + "from floris import FlorisModel\n", + "\n", + "fmodel = FlorisModel(\"defaults\")\n", + "\n", + "time_series = TimeSeries(\n", + " wind_directions=np.array([270.0, 270.0, 280.0]),\n", + " wind_speeds=np.array([8.0, 10.0, 12.0]),\n", + " turbulence_intensities=np.array([0.06, 0.06, 0.06]),\n", + ")\n", + "\n", + "fmodel.set(\n", + " layout_x = [0.0, 500.0],\n", + " layout_y = [0.0, 0.0],\n", + " wind_data=time_series,\n", + ")\n", + "\n", + "fmodel.run()\n", + "\n", + "print(\"Powers [W]:\\n\", fmodel.get_turbine_powers(), \"\\n\")\n", + "print(\"Thrust coefficients [-]:\\n\", fmodel.get_turbine_thrust_coefficients(), \"\\n\")\n", + "print(\"Axial induction factors [-]:\\n\", fmodel.get_turbine_axial_induction_factors(), \"\\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c7d9b5ae", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Powers [W]:\n", + " [[ -80385.81346439 35955.07110895]\n", + " [-151917.60066 85753.35035653]\n", + " [-190271.12187713 332785.69634393]] \n", + "\n", + "Thrust coefficients [-]:\n", + " [[0.73380279 0.74621482]\n", + " [0.66198028 0.74239241]\n", + " [0.41175519 0.5029464 ]] \n", + "\n", + "Axial induction factors [-]:\n", + " [[0.34782061 0.35018336]\n", + " [0.30308838 0.35179638]\n", + " [0.18725075 0.22345784]] \n", + "\n" + ] + } + ], + "source": [ + "from floris import FlorisModel, TimeSeries\n", + "\n", + "fmodel = FlorisModel(\"defaults\")\n", + "\n", + "time_series = TimeSeries(\n", + " wind_directions=np.array([270.0, 270.0, 280.0]),\n", + " wind_speeds=np.array([8.0, 10.0, 12.0]),\n", + " turbulence_intensities=np.array([0.06, 0.06, 0.06]),\n", + ")\n", + "\n", + "yaw_angles = np.array([\n", + " [10.0, 0.0], # condition 1\n", + " [10.0, 0.0], # condition 2\n", + " [10.0, 0.0], # condition 3\n", + "])\n", + "\n", + "fmodel.set(\n", + " layout_x = [0.0, 500.0],\n", + " layout_y = [0.0, 0.0],\n", + " wind_data = time_series,\n", + " yaw_angles = yaw_angles\n", + ")\n", + "\n", + "fmodel.set_operation_model(MITRotorTurbine())\n", + "fmodel.run()\n", + "\n", + "print(\"Powers [W]:\\n\", fmodel.get_turbine_powers(), \"\\n\")\n", + "print(\"Thrust coefficients [-]:\\n\", fmodel.get_turbine_thrust_coefficients(), \"\\n\")\n", + "print(\"Axial induction factors [-]:\\n\", fmodel.get_turbine_axial_induction_factors(), \"\\n\")" + ] + }, { "cell_type": "code", "execution_count": null, - "id": "a2cdf23d", + "id": "de761cdd", "metadata": {}, "outputs": [], "source": [] diff --git a/examples/example_05_floris_integration.py b/examples/example_05_floris_integration.py new file mode 100644 index 0000000..093b0cb --- /dev/null +++ b/examples/example_05_floris_integration.py @@ -0,0 +1,35 @@ +from MITRotor.FlorisInterface.FlorisInterface import csv_to_interp, MITRotorTurbine +from floris import FlorisModel, TimeSeries +from floris.core.turbine.unified_momentum_model import UnifiedMomentumModelTurbine +import numpy as np +import matplotlib.pyplot as plt + +from floris import FlorisModel, TimeSeries + +fmodel = FlorisModel("defaults") +time_series = TimeSeries( + wind_directions=np.array([270.0, 270.0, 280.0]), + wind_speeds=np.array([8.0, 10.0, 12.0]), + turbulence_intensities=np.array([0.06, 0.06, 0.06]), +) +yaw_angles = np.array([ + [0.0, 0.0], # condition 1 + [0.0, 0.0], # condition 2 + [0.0, 0.0], # condition 3 +]) + +fmodel.set( + layout_x = [0.0, 500.0], + layout_y = [0.0, 0.0], + wind_data = time_series, + yaw_angles = yaw_angles +) +fmodel.set_operation_model(UnifiedMomentumModelTurbine) + +# fmodel.set_operation_model(MITRotorTurbine()) + +fmodel.run() + +print("Powers [W]:\n", fmodel.get_turbine_powers(), "\n") +print("Thrust coefficients [-]:\n", fmodel.get_turbine_thrust_coefficients(), "\n") +print("Axial induction factors [-]:\n", fmodel.get_turbine_axial_induction_factors(), "\n") \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index b1ad6e6..c90a865 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,24 +2,23 @@ [[package]] name = "anyio" -version = "4.11.0" +version = "4.12.0" description = "High-level concurrency and networking framework on top of asyncio or Trio" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc"}, - {file = "anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4"}, + {file = "anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb"}, + {file = "anyio-4.12.0.tar.gz", hash = "sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0"}, ] [package.dependencies] exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" -sniffio = ">=1.1" typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} [package.extras] -trio = ["trio (>=0.31.0)"] +trio = ["trio (>=0.31.0) ; python_version < \"3.10\"", "trio (>=0.32.0) ; python_version >= \"3.10\""] [[package]] name = "appnope" @@ -28,7 +27,7 @@ description = "Disable App Nap on macOS >= 10.9" optional = false python-versions = ">=3.6" groups = ["dev"] -markers = "platform_system == \"Darwin\" or sys_platform == \"darwin\" and python_version < \"3.11\"" +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"}, @@ -113,19 +112,19 @@ test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock [[package]] name = "asttokens" -version = "3.0.0" +version = "3.0.1" description = "Annotate AST trees with source code positions" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2"}, - {file = "asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7"}, + {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,<4)"] -test = ["astroid (>=2,<4)", "pytest", "pytest-cov", "pytest-xdist"] +astroid = ["astroid (>=2,<5)"] +test = ["astroid (>=2,<5)", "pytest (<9.0)", "pytest-cov", "pytest-xdist"] [[package]] name = "async-lru" @@ -169,33 +168,20 @@ files = [ [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 = "backcall" -version = "0.2.0" -description = "Specifications for callback functions passed in to an API" -optional = false -python-versions = "*" -groups = ["dev"] -markers = "python_version < \"3.11\"" -files = [ - {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, - {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, -] - [[package]] name = "beautifulsoup4" -version = "4.14.2" +version = "4.14.3" description = "Screen-scraping library" optional = false python-versions = ">=3.7.0" groups = ["dev"] files = [ - {file = "beautifulsoup4-4.14.2-py3-none-any.whl", hash = "sha256:5ef6fa3a8cbece8488d66985560f97ed091e22bbc4e9c2338508a9d5de6d4515"}, - {file = "beautifulsoup4-4.14.2.tar.gz", hash = "sha256:2a98ab9f944a11acee9cc848508ec28d9228abfd522ef0fad6a02a72e0ded69e"}, + {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.2" +soupsieve = ">=1.6.1" typing-extensions = ">=4.0.0" [package.extras] @@ -256,24 +242,23 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "bleach" -version = "6.1.0" +version = "6.2.0" description = "An easy safelist-based HTML-sanitizing tool." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] markers = "python_version < \"3.11\"" files = [ - {file = "bleach-6.1.0-py3-none-any.whl", hash = "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6"}, - {file = "bleach-6.1.0.tar.gz", hash = "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe"}, + {file = "bleach-6.2.0-py3-none-any.whl", hash = "sha256:117d9c6097a7c3d22fd578fcd8d35ff1e125df6736f554da4e432fdd63f31e5e"}, + {file = "bleach-6.2.0.tar.gz", hash = "sha256:123e894118b8a599fd80d3ec1a6d4cc7ce4e5882b1317a7e1ba69b56e95f991f"}, ] [package.dependencies] -six = ">=1.9.0" -tinycss2 = {version = ">=1.1.0,<1.3", optional = true, markers = "extra == \"css\""} +tinycss2 = {version = ">=1.1.0,<1.5", optional = true, markers = "extra == \"css\""} webencodings = "*" [package.extras] -css = ["tinycss2 (>=1.1.0,<1.3)"] +css = ["tinycss2 (>=1.1.0,<1.5)"] [[package]] name = "bleach" @@ -297,14 +282,14 @@ css = ["tinycss2 (>=1.1.0,<1.5)"] [[package]] name = "certifi" -version = "2025.10.5" +version = "2026.1.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.7" groups = ["dev"] files = [ - {file = "certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de"}, - {file = "certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43"}, + {file = "certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c"}, + {file = "certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120"}, ] [[package]] @@ -545,15 +530,15 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "click" -version = "8.3.0" +version = "8.3.1" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.10" groups = ["dev"] markers = "python_version >= \"3.11\"" files = [ - {file = "click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc"}, - {file = "click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4"}, + {file = "click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6"}, + {file = "click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a"}, ] [package.dependencies] @@ -802,42 +787,42 @@ tests = ["pytest", "pytest-cov", "pytest-xdist"] [[package]] name = "debugpy" -version = "1.8.17" +version = "1.8.19" description = "An implementation of the Debug Adapter Protocol for Python" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "debugpy-1.8.17-cp310-cp310-macosx_15_0_x86_64.whl", hash = "sha256:c41d2ce8bbaddcc0009cc73f65318eedfa3dbc88a8298081deb05389f1ab5542"}, - {file = "debugpy-1.8.17-cp310-cp310-manylinux_2_34_x86_64.whl", hash = "sha256:1440fd514e1b815edd5861ca394786f90eb24960eb26d6f7200994333b1d79e3"}, - {file = "debugpy-1.8.17-cp310-cp310-win32.whl", hash = "sha256:3a32c0af575749083d7492dc79f6ab69f21b2d2ad4cd977a958a07d5865316e4"}, - {file = "debugpy-1.8.17-cp310-cp310-win_amd64.whl", hash = "sha256:a3aad0537cf4d9c1996434be68c6c9a6d233ac6f76c2a482c7803295b4e4f99a"}, - {file = "debugpy-1.8.17-cp311-cp311-macosx_15_0_universal2.whl", hash = "sha256:d3fce3f0e3de262a3b67e69916d001f3e767661c6e1ee42553009d445d1cd840"}, - {file = "debugpy-1.8.17-cp311-cp311-manylinux_2_34_x86_64.whl", hash = "sha256:c6bdf134457ae0cac6fb68205776be635d31174eeac9541e1d0c062165c6461f"}, - {file = "debugpy-1.8.17-cp311-cp311-win32.whl", hash = "sha256:e79a195f9e059edfe5d8bf6f3749b2599452d3e9380484cd261f6b7cd2c7c4da"}, - {file = "debugpy-1.8.17-cp311-cp311-win_amd64.whl", hash = "sha256:b532282ad4eca958b1b2d7dbcb2b7218e02cb934165859b918e3b6ba7772d3f4"}, - {file = "debugpy-1.8.17-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:f14467edef672195c6f6b8e27ce5005313cb5d03c9239059bc7182b60c176e2d"}, - {file = "debugpy-1.8.17-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:24693179ef9dfa20dca8605905a42b392be56d410c333af82f1c5dff807a64cc"}, - {file = "debugpy-1.8.17-cp312-cp312-win32.whl", hash = "sha256:6a4e9dacf2cbb60d2514ff7b04b4534b0139facbf2abdffe0639ddb6088e59cf"}, - {file = "debugpy-1.8.17-cp312-cp312-win_amd64.whl", hash = "sha256:e8f8f61c518952fb15f74a302e068b48d9c4691768ade433e4adeea961993464"}, - {file = "debugpy-1.8.17-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:857c1dd5d70042502aef1c6d1c2801211f3ea7e56f75e9c335f434afb403e464"}, - {file = "debugpy-1.8.17-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:3bea3b0b12f3946e098cce9b43c3c46e317b567f79570c3f43f0b96d00788088"}, - {file = "debugpy-1.8.17-cp313-cp313-win32.whl", hash = "sha256:e34ee844c2f17b18556b5bbe59e1e2ff4e86a00282d2a46edab73fd7f18f4a83"}, - {file = "debugpy-1.8.17-cp313-cp313-win_amd64.whl", hash = "sha256:6c5cd6f009ad4fca8e33e5238210dc1e5f42db07d4b6ab21ac7ffa904a196420"}, - {file = "debugpy-1.8.17-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:045290c010bcd2d82bc97aa2daf6837443cd52f6328592698809b4549babcee1"}, - {file = "debugpy-1.8.17-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:b69b6bd9dba6a03632534cdf67c760625760a215ae289f7489a452af1031fe1f"}, - {file = "debugpy-1.8.17-cp314-cp314-win32.whl", hash = "sha256:5c59b74aa5630f3a5194467100c3b3d1c77898f9ab27e3f7dc5d40fc2f122670"}, - {file = "debugpy-1.8.17-cp314-cp314-win_amd64.whl", hash = "sha256:893cba7bb0f55161de4365584b025f7064e1f88913551bcd23be3260b231429c"}, - {file = "debugpy-1.8.17-cp38-cp38-macosx_15_0_x86_64.whl", hash = "sha256:8deb4e31cd575c9f9370042876e078ca118117c1b5e1f22c32befcfbb6955f0c"}, - {file = "debugpy-1.8.17-cp38-cp38-manylinux_2_34_x86_64.whl", hash = "sha256:b75868b675949a96ab51abc114c7163f40ff0d8f7d6d5fd63f8932fd38e9c6d7"}, - {file = "debugpy-1.8.17-cp38-cp38-win32.whl", hash = "sha256:17e456da14848d618662354e1dccfd5e5fb75deec3d1d48dc0aa0baacda55860"}, - {file = "debugpy-1.8.17-cp38-cp38-win_amd64.whl", hash = "sha256:e851beb536a427b5df8aa7d0c7835b29a13812f41e46292ff80b2ef77327355a"}, - {file = "debugpy-1.8.17-cp39-cp39-macosx_15_0_x86_64.whl", hash = "sha256:f2ac8055a0c4a09b30b931100996ba49ef334c6947e7ae365cdd870416d7513e"}, - {file = "debugpy-1.8.17-cp39-cp39-manylinux_2_34_x86_64.whl", hash = "sha256:eaa85bce251feca8e4c87ce3b954aba84b8c645b90f0e6a515c00394a9f5c0e7"}, - {file = "debugpy-1.8.17-cp39-cp39-win32.whl", hash = "sha256:b13eea5587e44f27f6c48588b5ad56dcb74a4f3a5f89250443c94587f3eb2ea1"}, - {file = "debugpy-1.8.17-cp39-cp39-win_amd64.whl", hash = "sha256:bb1bbf92317e1f35afcf3ef0450219efb3afe00be79d8664b250ac0933b9015f"}, - {file = "debugpy-1.8.17-py2.py3-none-any.whl", hash = "sha256:60c7dca6571efe660ccb7a9508d73ca14b8796c4ed484c2002abba714226cfef"}, - {file = "debugpy-1.8.17.tar.gz", hash = "sha256:fd723b47a8c08892b1a16b2c6239a8b96637c62a59b94bb5dab4bac592a58a8e"}, + {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]] @@ -882,15 +867,15 @@ profile = ["gprof2dot (>=2022.7.29)"] [[package]] name = "exceptiongroup" -version = "1.3.0" +version = "1.3.1" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" groups = ["dev"] markers = "python_version < \"3.11\"" files = [ - {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}, - {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}, + {file = "exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"}, + {file = "exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"}, ] [package.dependencies] @@ -931,15 +916,13 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc [[package]] name = "floris" -version = "4.5.1" +version = "4.5" description = "A controls-oriented engineering wake model." optional = false python-versions = ">=3.9" groups = ["main"] -files = [ - {file = "floris-4.5.1-py3-none-any.whl", hash = "sha256:85dd2669319c3f4987a8231862eb2cb219c6738c9c042135f734d95b593d6961"}, - {file = "floris-4.5.1.tar.gz", hash = "sha256:7823f1a0d1d286fe2e6347972aaaef70d219b95e1c01e579e1bfadfd14a12504"}, -] +files = [] +develop = false [package.dependencies] attrs = "*" @@ -957,85 +940,166 @@ shapely = ">=2.0,<3.0" develop = ["isort (>=5.0,<6.0)", "pre-commit (>=4.0,<5.0)", "pytest (>=8.0,<9.0)", "pytest-benchmark (>=5.1,<6.0)", "ruff (>=0.9,<1.0)"] docs = ["bokeh (>=3.7,<4.0)", "jupyter-book (>=1.0,<2.0)", "sphinx-autodoc-typehints (>=2.0,<3.0)", "sphinx-book-theme (>=1.0,<2.0)", "sphinxcontrib-autoyaml (>=1.0,<2.0)", "sphinxcontrib.mermaid (>=1.0,<2.0)"] +[package.source] +type = "git" +url = "https://github.com/misi9170/floris.git" +reference = "feature/user-def-op-mod" +resolved_reference = "9c8fca03f1520ea943c3080ac1e3ec8294f2663d" + [[package]] name = "fonttools" -version = "4.60.1" +version = "4.60.2" description = "Tools to manipulate font files" optional = false python-versions = ">=3.9" groups = ["main", "examples"] +markers = "python_version < \"3.11\"" +files = [ + {file = "fonttools-4.60.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4e36fadcf7e8ca6e34d490eef86ed638d6fd9c55d2f514b05687622cfc4a7050"}, + {file = "fonttools-4.60.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6e500fc9c04bee749ceabfc20cb4903f6981c2139050d85720ea7ada61b75d5c"}, + {file = "fonttools-4.60.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22efea5e784e1d1cd8d7b856c198e360a979383ebc6dea4604743b56da1cbc34"}, + {file = "fonttools-4.60.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:677aa92d84d335e4d301d8ba04afca6f575316bc647b6782cb0921943fcb6343"}, + {file = "fonttools-4.60.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:edd49d3defbf35476e78b61ff737ff5efea811acff68d44233a95a5a48252334"}, + {file = "fonttools-4.60.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:126839492b69cecc5baf2bddcde60caab2ffafd867bbae2a88463fce6078ca3a"}, + {file = "fonttools-4.60.2-cp310-cp310-win32.whl", hash = "sha256:ffcab6f5537136046ca902ed2491ab081ba271b07591b916289b7c27ff845f96"}, + {file = "fonttools-4.60.2-cp310-cp310-win_amd64.whl", hash = "sha256:9c68b287c7ffcd29dd83b5f961004b2a54a862a88825d52ea219c6220309ba45"}, + {file = "fonttools-4.60.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a2aed0a7931401b3875265717a24c726f87ecfedbb7b3426c2ca4d2812e281ae"}, + {file = "fonttools-4.60.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dea6868e9d2b816c9076cfea77754686f3c19149873bdbc5acde437631c15df1"}, + {file = "fonttools-4.60.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2fa27f34950aa1fe0f0b1abe25eed04770a3b3b34ad94e5ace82cc341589678a"}, + {file = "fonttools-4.60.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:13a53d479d187b09bfaa4a35ffcbc334fc494ff355f0a587386099cb66674f1e"}, + {file = "fonttools-4.60.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fac5e921d3bd0ca3bb8517dced2784f0742bc8ca28579a68b139f04ea323a779"}, + {file = "fonttools-4.60.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:648f4f9186fd7f1f3cd57dbf00d67a583720d5011feca67a5e88b3a491952cfb"}, + {file = "fonttools-4.60.2-cp311-cp311-win32.whl", hash = "sha256:3274e15fad871bead5453d5ce02658f6d0c7bc7e7021e2a5b8b04e2f9e40da1a"}, + {file = "fonttools-4.60.2-cp311-cp311-win_amd64.whl", hash = "sha256:91d058d5a483a1525b367803abb69de0923fbd45e1f82ebd000f5c8aa65bc78e"}, + {file = "fonttools-4.60.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e0164b7609d2b5c5dd4e044b8085b7bd7ca7363ef8c269a4ab5b5d4885a426b2"}, + {file = "fonttools-4.60.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1dd3d9574fc595c1e97faccae0f264dc88784ddf7fbf54c939528378bacc0033"}, + {file = "fonttools-4.60.2-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:98d0719f1b11c2817307d2da2e94296a3b2a3503f8d6252a101dca3ee663b917"}, + {file = "fonttools-4.60.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9d3ea26957dd07209f207b4fff64c702efe5496de153a54d3b91007ec28904dd"}, + {file = "fonttools-4.60.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1ee301273b0850f3a515299f212898f37421f42ff9adfc341702582ca5073c13"}, + {file = "fonttools-4.60.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c6eb4694cc3b9c03b7c01d65a9cf35b577f21aa6abdbeeb08d3114b842a58153"}, + {file = "fonttools-4.60.2-cp312-cp312-win32.whl", hash = "sha256:57f07b616c69c244cc1a5a51072eeef07dddda5ebef9ca5c6e9cf6d59ae65b70"}, + {file = "fonttools-4.60.2-cp312-cp312-win_amd64.whl", hash = "sha256:310035802392f1fe5a7cf43d76f6ff4a24c919e4c72c0352e7b8176e2584b8a0"}, + {file = "fonttools-4.60.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2bb5fd231e56ccd7403212636dcccffc96c5ae0d6f9e4721fa0a32cb2e3ca432"}, + {file = "fonttools-4.60.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:536b5fab7b6fec78ccf59b5c59489189d9d0a8b0d3a77ed1858be59afb096696"}, + {file = "fonttools-4.60.2-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6b9288fc38252ac86a9570f19313ecbc9ff678982e0f27c757a85f1f284d3400"}, + {file = "fonttools-4.60.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:93fcb420791d839ef592eada2b69997c445d0ce9c969b5190f2e16828ec10607"}, + {file = "fonttools-4.60.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7916a381b094db4052ac284255186aebf74c5440248b78860cb41e300036f598"}, + {file = "fonttools-4.60.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:58c8c393d5e16b15662cfc2d988491940458aa87894c662154f50c7b49440bef"}, + {file = "fonttools-4.60.2-cp313-cp313-win32.whl", hash = "sha256:19c6e0afd8b02008caa0aa08ab896dfce5d0bcb510c49b2c499541d5cb95a963"}, + {file = "fonttools-4.60.2-cp313-cp313-win_amd64.whl", hash = "sha256:6a500dc59e11b2338c2dba1f8cf11a4ae8be35ec24af8b2628b8759a61457b76"}, + {file = "fonttools-4.60.2-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:9387c532acbe323bbf2a920f132bce3c408a609d5f9dcfc6532fbc7e37f8ccbb"}, + {file = "fonttools-4.60.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e6f1c824185b5b8fb681297f315f26ae55abb0d560c2579242feea8236b1cfef"}, + {file = "fonttools-4.60.2-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:55a3129d1e4030b1a30260f1b32fe76781b585fb2111d04a988e141c09eb6403"}, + {file = "fonttools-4.60.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b196e63753abc33b3b97a6fd6de4b7c4fef5552c0a5ba5e562be214d1e9668e0"}, + {file = "fonttools-4.60.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:de76c8d740fb55745f3b154f0470c56db92ae3be27af8ad6c2e88f1458260c9a"}, + {file = "fonttools-4.60.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6ba6303225c95998c9fda2d410aa792c3d2c1390a09df58d194b03e17583fa25"}, + {file = "fonttools-4.60.2-cp314-cp314-win32.whl", hash = "sha256:0a89728ce10d7c816fedaa5380c06d2793e7a8a634d7ce16810e536c22047384"}, + {file = "fonttools-4.60.2-cp314-cp314-win_amd64.whl", hash = "sha256:fa8446e6ab8bd778b82cb1077058a2addba86f30de27ab9cc18ed32b34bc8667"}, + {file = "fonttools-4.60.2-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:4063bc81ac5a4137642865cb63dd270e37b3cd1f55a07c0d6e41d072699ccca2"}, + {file = "fonttools-4.60.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ebfdb66fa69732ed604ab8e2a0431e6deff35e933a11d73418cbc7823d03b8e1"}, + {file = "fonttools-4.60.2-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:50b10b3b1a72d1d54c61b0e59239e1a94c0958f4a06a1febf97ce75388dd91a4"}, + {file = "fonttools-4.60.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:beae16891a13b4a2ddec9b39b4de76092a3025e4d1c82362e3042b62295d5e4d"}, + {file = "fonttools-4.60.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:522f017fdb3766fd5d2d321774ef351cc6ce88ad4e6ac9efe643e4a2b9d528db"}, + {file = "fonttools-4.60.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:82cceceaf9c09a965a75b84a4b240dd3768e596ffb65ef53852681606fe7c9ba"}, + {file = "fonttools-4.60.2-cp314-cp314t-win32.whl", hash = "sha256:bbfbc918a75437fe7e6d64d1b1e1f713237df1cf00f3a36dedae910b2ba01cee"}, + {file = "fonttools-4.60.2-cp314-cp314t-win_amd64.whl", hash = "sha256:0e5cd9b0830f6550d58c84f3ab151a9892b50c4f9d538c5603c0ce6fff2eb3f1"}, + {file = "fonttools-4.60.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a3c75b8b42f7f93906bdba9eb1197bb76aecbe9a0a7cf6feec75f7605b5e8008"}, + {file = "fonttools-4.60.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0f86c8c37bc0ec0b9c141d5e90c717ff614e93c187f06d80f18c7057097f71bc"}, + {file = "fonttools-4.60.2-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe905403fe59683b0e9a45f234af2866834376b8821f34633b1c76fb731b6311"}, + {file = "fonttools-4.60.2-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38ce703b60a906e421e12d9e3a7f064883f5e61bb23e8961f4be33cfe578500b"}, + {file = "fonttools-4.60.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9e810c06f3e79185cecf120e58b343ea5a89b54dd695fd644446bcf8c026da5e"}, + {file = "fonttools-4.60.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:38faec8cc1d12122599814d15a402183f5123fb7608dac956121e7c6742aebc5"}, + {file = "fonttools-4.60.2-cp39-cp39-win32.whl", hash = "sha256:80a45cf7bf659acb7b36578f300231873daba67bd3ca8cce181c73f861f14a37"}, + {file = "fonttools-4.60.2-cp39-cp39-win_amd64.whl", hash = "sha256:c355d5972071938e1b1e0f5a1df001f68ecf1a62f34a3407dc8e0beccf052501"}, + {file = "fonttools-4.60.2-py3-none-any.whl", hash = "sha256:73cf92eeda67cf6ff10c8af56fc8f4f07c1647d989a979be9e388a49be26552a"}, + {file = "fonttools-4.60.2.tar.gz", hash = "sha256:d29552e6b155ebfc685b0aecf8d429cb76c14ab734c22ef5d3dea6fdf800c92c"}, +] + +[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 = "fonttools" +version = "4.61.1" +description = "Tools to manipulate font files" +optional = false +python-versions = ">=3.10" +groups = ["main", "examples"] +markers = "python_version >= \"3.11\"" files = [ - {file = "fonttools-4.60.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9a52f254ce051e196b8fe2af4634c2d2f02c981756c6464dc192f1b6050b4e28"}, - {file = "fonttools-4.60.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7420a2696a44650120cdd269a5d2e56a477e2bfa9d95e86229059beb1c19e15"}, - {file = "fonttools-4.60.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee0c0b3b35b34f782afc673d503167157094a16f442ace7c6c5e0ca80b08f50c"}, - {file = "fonttools-4.60.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:282dafa55f9659e8999110bd8ed422ebe1c8aecd0dc396550b038e6c9a08b8ea"}, - {file = "fonttools-4.60.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4ba4bd646e86de16160f0fb72e31c3b9b7d0721c3e5b26b9fa2fc931dfdb2652"}, - {file = "fonttools-4.60.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0b0835ed15dd5b40d726bb61c846a688f5b4ce2208ec68779bc81860adb5851a"}, - {file = "fonttools-4.60.1-cp310-cp310-win32.whl", hash = "sha256:1525796c3ffe27bb6268ed2a1bb0dcf214d561dfaf04728abf01489eb5339dce"}, - {file = "fonttools-4.60.1-cp310-cp310-win_amd64.whl", hash = "sha256:268ecda8ca6cb5c4f044b1fb9b3b376e8cd1b361cef275082429dc4174907038"}, - {file = "fonttools-4.60.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7b4c32e232a71f63a5d00259ca3d88345ce2a43295bb049d21061f338124246f"}, - {file = "fonttools-4.60.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3630e86c484263eaac71d117085d509cbcf7b18f677906824e4bace598fb70d2"}, - {file = "fonttools-4.60.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5c1015318e4fec75dd4943ad5f6a206d9727adf97410d58b7e32ab644a807914"}, - {file = "fonttools-4.60.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e6c58beb17380f7c2ea181ea11e7db8c0ceb474c9dd45f48e71e2cb577d146a1"}, - {file = "fonttools-4.60.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec3681a0cb34c255d76dd9d865a55f260164adb9fa02628415cdc2d43ee2c05d"}, - {file = "fonttools-4.60.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f4b5c37a5f40e4d733d3bbaaef082149bee5a5ea3156a785ff64d949bd1353fa"}, - {file = "fonttools-4.60.1-cp311-cp311-win32.whl", hash = "sha256:398447f3d8c0c786cbf1209711e79080a40761eb44b27cdafffb48f52bcec258"}, - {file = "fonttools-4.60.1-cp311-cp311-win_amd64.whl", hash = "sha256:d066ea419f719ed87bc2c99a4a4bfd77c2e5949cb724588b9dd58f3fd90b92bf"}, - {file = "fonttools-4.60.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:7b0c6d57ab00dae9529f3faf187f2254ea0aa1e04215cf2f1a8ec277c96661bc"}, - {file = "fonttools-4.60.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:839565cbf14645952d933853e8ade66a463684ed6ed6c9345d0faf1f0e868877"}, - {file = "fonttools-4.60.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8177ec9676ea6e1793c8a084a90b65a9f778771998eb919d05db6d4b1c0b114c"}, - {file = "fonttools-4.60.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:996a4d1834524adbb423385d5a629b868ef9d774670856c63c9a0408a3063401"}, - {file = "fonttools-4.60.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a46b2f450bc79e06ef3b6394f0c68660529ed51692606ad7f953fc2e448bc903"}, - {file = "fonttools-4.60.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6ec722ee589e89a89f5b7574f5c45604030aa6ae24cb2c751e2707193b466fed"}, - {file = "fonttools-4.60.1-cp312-cp312-win32.whl", hash = "sha256:b2cf105cee600d2de04ca3cfa1f74f1127f8455b71dbad02b9da6ec266e116d6"}, - {file = "fonttools-4.60.1-cp312-cp312-win_amd64.whl", hash = "sha256:992775c9fbe2cf794786fa0ffca7f09f564ba3499b8fe9f2f80bd7197db60383"}, - {file = "fonttools-4.60.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6f68576bb4bbf6060c7ab047b1574a1ebe5c50a17de62830079967b211059ebb"}, - {file = "fonttools-4.60.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:eedacb5c5d22b7097482fa834bda0dafa3d914a4e829ec83cdea2a01f8c813c4"}, - {file = "fonttools-4.60.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b33a7884fabd72bdf5f910d0cf46be50dce86a0362a65cfc746a4168c67eb96c"}, - {file = "fonttools-4.60.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2409d5fb7b55fd70f715e6d34e7a6e4f7511b8ad29a49d6df225ee76da76dd77"}, - {file = "fonttools-4.60.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c8651e0d4b3bdeda6602b85fdc2abbefc1b41e573ecb37b6779c4ca50753a199"}, - {file = "fonttools-4.60.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:145daa14bf24824b677b9357c5e44fd8895c2a8f53596e1b9ea3496081dc692c"}, - {file = "fonttools-4.60.1-cp313-cp313-win32.whl", hash = "sha256:2299df884c11162617a66b7c316957d74a18e3758c0274762d2cc87df7bc0272"}, - {file = "fonttools-4.60.1-cp313-cp313-win_amd64.whl", hash = "sha256:a3db56f153bd4c5c2b619ab02c5db5192e222150ce5a1bc10f16164714bc39ac"}, - {file = "fonttools-4.60.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:a884aef09d45ba1206712c7dbda5829562d3fea7726935d3289d343232ecb0d3"}, - {file = "fonttools-4.60.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8a44788d9d91df72d1a5eac49b31aeb887a5f4aab761b4cffc4196c74907ea85"}, - {file = "fonttools-4.60.1-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e852d9dda9f93ad3651ae1e3bb770eac544ec93c3807888798eccddf84596537"}, - {file = "fonttools-4.60.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:154cb6ee417e417bf5f7c42fe25858c9140c26f647c7347c06f0cc2d47eff003"}, - {file = "fonttools-4.60.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5664fd1a9ea7f244487ac8f10340c4e37664675e8667d6fee420766e0fb3cf08"}, - {file = "fonttools-4.60.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:583b7f8e3c49486e4d489ad1deacfb8d5be54a8ef34d6df824f6a171f8511d99"}, - {file = "fonttools-4.60.1-cp314-cp314-win32.whl", hash = "sha256:66929e2ea2810c6533a5184f938502cfdaea4bc3efb7130d8cc02e1c1b4108d6"}, - {file = "fonttools-4.60.1-cp314-cp314-win_amd64.whl", hash = "sha256:f3d5be054c461d6a2268831f04091dc82753176f6ea06dc6047a5e168265a987"}, - {file = "fonttools-4.60.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:b6379e7546ba4ae4b18f8ae2b9bc5960936007a1c0e30b342f662577e8bc3299"}, - {file = "fonttools-4.60.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9d0ced62b59e0430b3690dbc5373df1c2aa7585e9a8ce38eff87f0fd993c5b01"}, - {file = "fonttools-4.60.1-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:875cb7764708b3132637f6c5fb385b16eeba0f7ac9fa45a69d35e09b47045801"}, - {file = "fonttools-4.60.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a184b2ea57b13680ab6d5fbde99ccef152c95c06746cb7718c583abd8f945ccc"}, - {file = "fonttools-4.60.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:026290e4ec76583881763fac284aca67365e0be9f13a7fb137257096114cb3bc"}, - {file = "fonttools-4.60.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f0e8817c7d1a0c2eedebf57ef9a9896f3ea23324769a9a2061a80fe8852705ed"}, - {file = "fonttools-4.60.1-cp314-cp314t-win32.whl", hash = "sha256:1410155d0e764a4615774e5c2c6fc516259fe3eca5882f034eb9bfdbee056259"}, - {file = "fonttools-4.60.1-cp314-cp314t-win_amd64.whl", hash = "sha256:022beaea4b73a70295b688f817ddc24ed3e3418b5036ffcd5658141184ef0d0c"}, - {file = "fonttools-4.60.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:122e1a8ada290423c493491d002f622b1992b1ab0b488c68e31c413390dc7eb2"}, - {file = "fonttools-4.60.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a140761c4ff63d0cb9256ac752f230460ee225ccef4ad8f68affc723c88e2036"}, - {file = "fonttools-4.60.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0eae96373e4b7c9e45d099d7a523444e3554360927225c1cdae221a58a45b856"}, - {file = "fonttools-4.60.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:596ecaca36367027d525b3b426d8a8208169d09edcf8c7506aceb3a38bfb55c7"}, - {file = "fonttools-4.60.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2ee06fc57512144d8b0445194c2da9f190f61ad51e230f14836286470c99f854"}, - {file = "fonttools-4.60.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b42d86938e8dda1cd9a1a87a6d82f1818eaf933348429653559a458d027446da"}, - {file = "fonttools-4.60.1-cp39-cp39-win32.whl", hash = "sha256:8b4eb332f9501cb1cd3d4d099374a1e1306783ff95489a1026bde9eb02ccc34a"}, - {file = "fonttools-4.60.1-cp39-cp39-win_amd64.whl", hash = "sha256:7473a8ed9ed09aeaa191301244a5a9dbe46fe0bf54f9d6cd21d83044c3321217"}, - {file = "fonttools-4.60.1-py3-none-any.whl", hash = "sha256:906306ac7afe2156fcf0042173d6ebbb05416af70f6b370967b47f8f00103bbb"}, - {file = "fonttools-4.60.1.tar.gz", hash = "sha256:ef00af0439ebfee806b25f24c8f92109157ff3fac5731dc7867957812e87b8d9"}, + {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.23.0)", "unicodedata2 (>=15.1.0) ; python_version <= \"3.12\"", "xattr ; sys_platform == \"darwin\"", "zopfli (>=0.1.4)"] +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.23.0)"] +repacker = ["uharfbuzz (>=0.45.0)"] symfont = ["sympy"] type1 = ["xattr ; sys_platform == \"darwin\""] -unicode = ["unicodedata2 (>=15.1.0) ; python_version <= \"3.12\""] +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]] @@ -1156,15 +1220,15 @@ all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2 [[package]] name = "importlib-metadata" -version = "8.5.0" +version = "8.7.1" description = "Read metadata from Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] markers = "python_version == \"3.9\"" files = [ - {file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"}, - {file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"}, + {file = "importlib_metadata-8.7.1-py3-none-any.whl", hash = "sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151"}, + {file = "importlib_metadata-8.7.1.tar.gz", hash = "sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb"}, ] [package.dependencies] @@ -1174,22 +1238,22 @@ zipp = ">=3.20" check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -enabler = ["pytest-enabler (>=2.2)"] +enabler = ["pytest-enabler (>=3.4)"] perf = ["ipython"] -test = ["flufl.flake8", "importlib-resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] -type = ["pytest-mypy"] +test = ["flufl.flake8", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +type = ["mypy (<1.19) ; platform_python_implementation == \"PyPy\"", "pytest-mypy (>=1.0.1)"] [[package]] name = "importlib-resources" -version = "6.4.5" +version = "6.5.2" description = "Read resources from Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["main", "examples"] markers = "python_version == \"3.9\"" files = [ - {file = "importlib_resources-6.4.5-py3-none-any.whl", hash = "sha256:ac29d5f956f01d5e4bb63102a5a19957f1b9175e45649977264a1416783bb717"}, - {file = "importlib_resources-6.4.5.tar.gz", hash = "sha256:980862a1d16c9e147a59603677fa2aa5fd82b87f223b6cb870695bcfce830065"}, + {file = "importlib_resources-6.5.2-py3-none-any.whl", hash = "sha256:789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec"}, + {file = "importlib_resources-6.5.2.tar.gz", hash = "sha256:185f87adef5bcc288449d98fb4fba07cea78bc036455dd44c5fc4a2fe78fed2c"}, ] [package.dependencies] @@ -1265,56 +1329,54 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0,<9)", "pytest-async [[package]] name = "ipython" -version = "8.12.3" +version = "8.18.1" description = "IPython: Productive Interactive Computing" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] markers = "python_version < \"3.11\"" files = [ - {file = "ipython-8.12.3-py3-none-any.whl", hash = "sha256:b0340d46a933d27c657b211a329d0be23793c36595acf9e6ef4164bc01a1804c"}, - {file = "ipython-8.12.3.tar.gz", hash = "sha256:3910c4b54543c2ad73d06579aa771041b7d5707b033bd488669b4cf544e3b363"}, + {file = "ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397"}, + {file = "ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27"}, ] [package.dependencies] -appnope = {version = "*", markers = "sys_platform == \"darwin\""} -backcall = "*" colorama = {version = "*", markers = "sys_platform == \"win32\""} decorator = "*" +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -pickleshare = "*" -prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" +prompt-toolkit = ">=3.0.41,<3.1.0" pygments = ">=2.4.0" stack-data = "*" traitlets = ">=5" typing-extensions = {version = "*", markers = "python_version < \"3.10\""} [package.extras] -all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] black = ["black"] -doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] nbformat = ["nbformat"] notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] -test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] +test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] [[package]] name = "ipython" -version = "8.37.0" +version = "8.38.0" description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.10" groups = ["dev"] markers = "python_version >= \"3.11\"" files = [ - {file = "ipython-8.37.0-py3-none-any.whl", hash = "sha256:ed87326596b878932dbcb171e3e698845434d8c61b8d8cd474bf663041a9dcf2"}, - {file = "ipython-8.37.0.tar.gz", hash = "sha256:ca815841e1a41a1e6b73a0b08f3038af9b2252564d01fc405356d34033012216"}, + {file = "ipython-8.38.0-py3-none-any.whl", hash = "sha256:750162629d800ac65bb3b543a14e7a74b0e88063eac9b92124d4b2aa3f6d8e86"}, + {file = "ipython-8.38.0.tar.gz", hash = "sha256:9cfea8c903ce0867cc2f23199ed8545eb741f3a69420bfcf3743ad1cec856d39"}, ] [package.dependencies] @@ -1345,14 +1407,14 @@ test-extra = ["curio", "ipython[test]", "jupyter_ai", "matplotlib (!=3.2.0)", "n [[package]] name = "ipywidgets" -version = "8.1.7" +version = "8.1.8" description = "Jupyter interactive widgets" optional = false python-versions = ">=3.7" groups = ["dev"] files = [ - {file = "ipywidgets-8.1.7-py3-none-any.whl", hash = "sha256:764f2602d25471c213919b8a1997df04bef869251db4ca8efba1b76b1bd9f7bb"}, - {file = "ipywidgets-8.1.7.tar.gz", hash = "sha256:15f1ac050b9ccbefd45dccfbb2ef6bed0029d8278682d569d71b8dd96bee0376"}, + {file = "ipywidgets-8.1.8-py3-none-any.whl", hash = "sha256:ecaca67aed704a338f88f67b1181b58f821ab5dc89c1f0f5ef99db43c1c2921e"}, + {file = "ipywidgets-8.1.8.tar.gz", hash = "sha256:61f969306b95f85fba6b6986b7fe45d73124d1d9e3023a8068710d47a22ea668"}, ] [package.dependencies] @@ -1420,19 +1482,16 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "json5" -version = "0.12.1" +version = "0.13.0" description = "A Python implementation of the JSON5 data format." optional = false python-versions = ">=3.8.0" groups = ["dev"] files = [ - {file = "json5-0.12.1-py3-none-any.whl", hash = "sha256:d9c9b3bc34a5f54d43c35e11ef7cb87d8bdd098c6ace87117a7b7e83e705c1d5"}, - {file = "json5-0.12.1.tar.gz", hash = "sha256:b2743e77b3242f8d03c143dd975a6ec7c52e2f2afe76ed934e53503dd4ad4990"}, + {file = "json5-0.13.0-py3-none-any.whl", hash = "sha256:9a08e1dd65f6a4d4c6fa82d216cf2477349ec2346a38fd70cc11d2557499fbcc"}, + {file = "json5-0.13.0.tar.gz", hash = "sha256:b1edf8d487721c0bf64d83c28e91280781f6e21f4a797d3261c7c828d4c165bf"}, ] -[package.extras] -dev = ["build (==1.2.2.post1)", "coverage (==7.5.4) ; python_version < \"3.9\"", "coverage (==7.8.0) ; python_version >= \"3.9\"", "mypy (==1.14.1) ; python_version < \"3.9\"", "mypy (==1.15.0) ; python_version >= \"3.9\"", "pip (==25.0.1)", "pylint (==3.2.7) ; python_version < \"3.9\"", "pylint (==3.3.6) ; python_version >= \"3.9\"", "ruff (==0.11.2)", "twine (==6.1.0)", "uv (==0.6.11)"] - [[package]] name = "jsonpointer" version = "3.0.0" @@ -1518,6 +1577,7 @@ description = "Jupyter protocol implementation and client libraries" optional = false python-versions = ">=3.8" groups = ["dev"] +markers = "python_version < \"3.11\"" files = [ {file = "jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f"}, {file = "jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419"}, @@ -1535,6 +1595,30 @@ traitlets = ">=5.3" docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko ; sys_platform == \"win32\"", "pre-commit", "pytest (<8.2.0)", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] +[[package]] +name = "jupyter-client" +version = "8.7.0" +description = "Jupyter protocol implementation and client libraries" +optional = false +python-versions = ">=3.10" +groups = ["dev"] +markers = "python_version >= \"3.11\"" +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-console" version = "6.6.3" @@ -1705,14 +1789,14 @@ test = ["jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-jupyter[server] (> [[package]] name = "jupyterlab" -version = "4.4.10" +version = "4.5.1" description = "JupyterLab computational environment" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "jupyterlab-4.4.10-py3-none-any.whl", hash = "sha256:65939ab4c8dcd0c42185c2d0d1a9d60b254dc8c46fc4fdb286b63c51e9358e07"}, - {file = "jupyterlab-4.4.10.tar.gz", hash = "sha256:521c017508af4e1d6d9d8a9d90f47a11c61197ad63b2178342489de42540a615"}, + {file = "jupyterlab-4.5.1-py3-none-any.whl", hash = "sha256:31b059de96de0754ff1f2ce6279774b6aab8c34d7082e9752db58207c99bd514"}, + {file = "jupyterlab-4.5.1.tar.gz", hash = "sha256:09da1ddfbd9eec18b5101dbb8515612aa1e47443321fb99503725a88e93d20d9"}, ] [package.dependencies] @@ -1724,7 +1808,7 @@ jinja2 = ">=3.0.3" jupyter-core = "*" jupyter-lsp = ">=2.0.0" jupyter-server = ">=2.4.0,<3" -jupyterlab-server = ">=2.27.1,<3" +jupyterlab-server = ">=2.28.0,<3" notebook-shim = ">=0.2" packaging = "*" setuptools = ">=41.1.0" @@ -1733,9 +1817,9 @@ tornado = ">=6.2.0" traitlets = "*" [package.extras] -dev = ["build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", "ruff (==0.11.4)"] +dev = ["build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", "ruff (==0.11.12)"] docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-jupyter", "sphinx (>=1.8,<8.2.0)", "sphinx-copybutton"] -docs-screenshots = ["altair (==5.5.0)", "ipython (==8.16.1)", "ipywidgets (==8.1.5)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.3.post1)", "matplotlib (==3.10.0)", "nbconvert (>=7.0.0)", "pandas (==2.2.3)", "scipy (==1.15.1)", "vega-datasets (==0.9.0)"] +docs-screenshots = ["altair (==6.0.0)", "ipython (==8.16.1)", "ipywidgets (==8.1.5)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.3.post1)", "matplotlib (==3.10.0)", "nbconvert (>=7.0.0)", "pandas (==2.2.3)", "scipy (==1.15.1)"] test = ["coverage", "pytest (>=7.0)", "pytest-check-links (>=0.7)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter (>=0.5.3)", "pytest-timeout", "pytest-tornasync", "requests", "requests-cache", "virtualenv"] upgrade-extension = ["copier (>=9,<10)", "jinja2-time (<0.3)", "pydantic (<3.0)", "pyyaml-include (<3.0)", "tomli-w (<2.0)"] @@ -1780,14 +1864,14 @@ test = ["hatch", "ipykernel", "openapi-core (>=0.18.0,<0.19.0)", "openapi-spec-v [[package]] name = "jupyterlab-widgets" -version = "3.0.15" +version = "3.0.16" description = "Jupyter interactive widgets for JupyterLab" optional = false python-versions = ">=3.7" groups = ["dev"] files = [ - {file = "jupyterlab_widgets-3.0.15-py3-none-any.whl", hash = "sha256:d59023d7d7ef71400d51e6fee9a88867f6e65e10a4201605d2d7f3e8f012a31c"}, - {file = "jupyterlab_widgets-3.0.15.tar.gz", hash = "sha256:2920888a0c2922351a9202817957a68c07d99673504d6cd37345299e971bb08b"}, + {file = "jupyterlab_widgets-3.0.16-py3-none-any.whl", hash = "sha256:45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8"}, + {file = "jupyterlab_widgets-3.0.16.tar.gz", hash = "sha256:423da05071d55cf27a9e602216d35a3a65a3e41cdf9c5d3b643b814ce38c19e0"}, ] [[package]] @@ -2045,6 +2129,93 @@ interegular = ["interegular (>=0.3.1,<0.4.0)"] nearley = ["js2py"] regex = ["regex"] +[[package]] +name = "librt" +version = "0.7.7" +description = "Mypyc runtime library" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +markers = "platform_python_implementation != \"PyPy\"" +files = [ + {file = "librt-0.7.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4836c5645f40fbdc275e5670819bde5ab5f2e882290d304e3c6ddab1576a6d0"}, + {file = "librt-0.7.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ae8aec43117a645a31e5f60e9e3a0797492e747823b9bda6972d521b436b4e8"}, + {file = "librt-0.7.7-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:aea05f701ccd2a76b34f0daf47ca5068176ff553510b614770c90d76ac88df06"}, + {file = "librt-0.7.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7b16ccaeff0ed4355dfb76fe1ea7a5d6d03b5ad27f295f77ee0557bc20a72495"}, + {file = "librt-0.7.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c48c7e150c095d5e3cea7452347ba26094be905d6099d24f9319a8b475fcd3e0"}, + {file = "librt-0.7.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4dcee2f921a8632636d1c37f1bbdb8841d15666d119aa61e5399c5268e7ce02e"}, + {file = "librt-0.7.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:14ef0f4ac3728ffd85bfc58e2f2f48fb4ef4fa871876f13a73a7381d10a9f77c"}, + {file = "librt-0.7.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e4ab69fa37f8090f2d971a5d2bc606c7401170dbdae083c393d6cbf439cb45b8"}, + {file = "librt-0.7.7-cp310-cp310-win32.whl", hash = "sha256:4bf3cc46d553693382d2abf5f5bd493d71bb0f50a7c0beab18aa13a5545c8900"}, + {file = "librt-0.7.7-cp310-cp310-win_amd64.whl", hash = "sha256:f0c8fe5aeadd8a0e5b0598f8a6ee3533135ca50fd3f20f130f9d72baf5c6ac58"}, + {file = "librt-0.7.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a487b71fbf8a9edb72a8c7a456dda0184642d99cd007bc819c0b7ab93676a8ee"}, + {file = "librt-0.7.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f4d4efb218264ecf0f8516196c9e2d1a0679d9fb3bb15df1155a35220062eba8"}, + {file = "librt-0.7.7-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b8bb331aad734b059c4b450cd0a225652f16889e286b2345af5e2c3c625c3d85"}, + {file = "librt-0.7.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:467dbd7443bda08338fc8ad701ed38cef48194017554f4c798b0a237904b3f99"}, + {file = "librt-0.7.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50d1d1ee813d2d1a3baf2873634ba506b263032418d16287c92ec1cc9c1a00cb"}, + {file = "librt-0.7.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c7e5070cf3ec92d98f57574da0224f8c73faf1ddd6d8afa0b8c9f6e86997bc74"}, + {file = "librt-0.7.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bdb9f3d865b2dafe7f9ad7f30ef563c80d0ddd2fdc8cc9b8e4f242f475e34d75"}, + {file = "librt-0.7.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8185c8497d45164e256376f9da5aed2bb26ff636c798c9dabe313b90e9f25b28"}, + {file = "librt-0.7.7-cp311-cp311-win32.whl", hash = "sha256:44d63ce643f34a903f09ff7ca355aae019a3730c7afd6a3c037d569beeb5d151"}, + {file = "librt-0.7.7-cp311-cp311-win_amd64.whl", hash = "sha256:7d13cc340b3b82134f8038a2bfe7137093693dcad8ba5773da18f95ad6b77a8a"}, + {file = "librt-0.7.7-cp311-cp311-win_arm64.whl", hash = "sha256:983de36b5a83fe9222f4f7dcd071f9b1ac6f3f17c0af0238dadfb8229588f890"}, + {file = "librt-0.7.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2a85a1fc4ed11ea0eb0a632459ce004a2d14afc085a50ae3463cd3dfe1ce43fc"}, + {file = "librt-0.7.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c87654e29a35938baead1c4559858f346f4a2a7588574a14d784f300ffba0efd"}, + {file = "librt-0.7.7-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c9faaebb1c6212c20afd8043cd6ed9de0a47d77f91a6b5b48f4e46ed470703fe"}, + {file = "librt-0.7.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1908c3e5a5ef86b23391448b47759298f87f997c3bd153a770828f58c2bb4630"}, + {file = "librt-0.7.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dbc4900e95a98fc0729523be9d93a8fedebb026f32ed9ffc08acd82e3e181503"}, + {file = "librt-0.7.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a7ea4e1fbd253e5c68ea0fe63d08577f9d288a73f17d82f652ebc61fa48d878d"}, + {file = "librt-0.7.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef7699b7a5a244b1119f85c5bbc13f152cd38240cbb2baa19b769433bae98e50"}, + {file = "librt-0.7.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:955c62571de0b181d9e9e0a0303c8bc90d47670a5eff54cf71bf5da61d1899cf"}, + {file = "librt-0.7.7-cp312-cp312-win32.whl", hash = "sha256:1bcd79be209313b270b0e1a51c67ae1af28adad0e0c7e84c3ad4b5cb57aaa75b"}, + {file = "librt-0.7.7-cp312-cp312-win_amd64.whl", hash = "sha256:4353ee891a1834567e0302d4bd5e60f531912179578c36f3d0430f8c5e16b456"}, + {file = "librt-0.7.7-cp312-cp312-win_arm64.whl", hash = "sha256:a76f1d679beccccdf8c1958e732a1dfcd6e749f8821ee59d7bec009ac308c029"}, + {file = "librt-0.7.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f4a0b0a3c86ba9193a8e23bb18f100d647bf192390ae195d84dfa0a10fb6244"}, + {file = "librt-0.7.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5335890fea9f9e6c4fdf8683061b9ccdcbe47c6dc03ab8e9b68c10acf78be78d"}, + {file = "librt-0.7.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9b4346b1225be26def3ccc6c965751c74868f0578cbcba293c8ae9168483d811"}, + {file = "librt-0.7.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a10b8eebdaca6e9fdbaf88b5aefc0e324b763a5f40b1266532590d5afb268a4c"}, + {file = "librt-0.7.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:067be973d90d9e319e6eb4ee2a9b9307f0ecd648b8a9002fa237289a4a07a9e7"}, + {file = "librt-0.7.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:23d2299ed007812cccc1ecef018db7d922733382561230de1f3954db28433977"}, + {file = "librt-0.7.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6b6f8ea465524aa4c7420c7cc4ca7d46fe00981de8debc67b1cc2e9957bb5b9d"}, + {file = "librt-0.7.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8df32a99cc46eb0ee90afd9ada113ae2cafe7e8d673686cf03ec53e49635439"}, + {file = "librt-0.7.7-cp313-cp313-win32.whl", hash = "sha256:86f86b3b785487c7760247bcdac0b11aa8bf13245a13ed05206286135877564b"}, + {file = "librt-0.7.7-cp313-cp313-win_amd64.whl", hash = "sha256:4862cb2c702b1f905c0503b72d9d4daf65a7fdf5a9e84560e563471e57a56949"}, + {file = "librt-0.7.7-cp313-cp313-win_arm64.whl", hash = "sha256:0996c83b1cb43c00e8c87835a284f9057bc647abd42b5871e5f941d30010c832"}, + {file = "librt-0.7.7-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:23daa1ab0512bafdd677eb1bfc9611d8ffbe2e328895671e64cb34166bc1b8c8"}, + {file = "librt-0.7.7-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:558a9e5a6f3cc1e20b3168fb1dc802d0d8fa40731f6e9932dcc52bbcfbd37111"}, + {file = "librt-0.7.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:2567cb48dc03e5b246927ab35cbb343376e24501260a9b5e30b8e255dca0d1d2"}, + {file = "librt-0.7.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6066c638cdf85ff92fc6f932d2d73c93a0e03492cdfa8778e6d58c489a3d7259"}, + {file = "librt-0.7.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a609849aca463074c17de9cda173c276eb8fee9e441053529e7b9e249dc8b8ee"}, + {file = "librt-0.7.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:add4e0a000858fe9bb39ed55f31085506a5c38363e6eb4a1e5943a10c2bfc3d1"}, + {file = "librt-0.7.7-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a3bfe73a32bd0bdb9a87d586b05a23c0a1729205d79df66dee65bb2e40d671ba"}, + {file = "librt-0.7.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:0ecce0544d3db91a40f8b57ae26928c02130a997b540f908cefd4d279d6c5848"}, + {file = "librt-0.7.7-cp314-cp314-win32.whl", hash = "sha256:8f7a74cf3a80f0c3b0ec75b0c650b2f0a894a2cec57ef75f6f72c1e82cdac61d"}, + {file = "librt-0.7.7-cp314-cp314-win_amd64.whl", hash = "sha256:3d1fe2e8df3268dd6734dba33ededae72ad5c3a859b9577bc00b715759c5aaab"}, + {file = "librt-0.7.7-cp314-cp314-win_arm64.whl", hash = "sha256:2987cf827011907d3dfd109f1be0d61e173d68b1270107bb0e89f2fca7f2ed6b"}, + {file = "librt-0.7.7-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8e92c8de62b40bfce91d5e12c6e8b15434da268979b1af1a6589463549d491e6"}, + {file = "librt-0.7.7-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f683dcd49e2494a7535e30f779aa1ad6e3732a019d80abe1309ea91ccd3230e3"}, + {file = "librt-0.7.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9b15e5d17812d4d629ff576699954f74e2cc24a02a4fc401882dd94f81daba45"}, + {file = "librt-0.7.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c084841b879c4d9b9fa34e5d5263994f21aea7fd9c6add29194dbb41a6210536"}, + {file = "librt-0.7.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10c8fb9966f84737115513fecbaf257f9553d067a7dd45a69c2c7e5339e6a8dc"}, + {file = "librt-0.7.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9b5fb1ecb2c35362eab2dbd354fd1efa5a8440d3e73a68be11921042a0edc0ff"}, + {file = "librt-0.7.7-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:d1454899909d63cc9199a89fcc4f81bdd9004aef577d4ffc022e600c412d57f3"}, + {file = "librt-0.7.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:7ef28f2e7a016b29792fe0a2dd04dec75725b32a1264e390c366103f834a9c3a"}, + {file = "librt-0.7.7-cp314-cp314t-win32.whl", hash = "sha256:5e419e0db70991b6ba037b70c1d5bbe92b20ddf82f31ad01d77a347ed9781398"}, + {file = "librt-0.7.7-cp314-cp314t-win_amd64.whl", hash = "sha256:d6b7d93657332c817b8d674ef6bf1ab7796b4f7ce05e420fd45bd258a72ac804"}, + {file = "librt-0.7.7-cp314-cp314t-win_arm64.whl", hash = "sha256:142c2cd91794b79fd0ce113bd658993b7ede0fe93057668c2f98a45ca00b7e91"}, + {file = "librt-0.7.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c8ffe3431d98cc043a14e88b21288b5ec7ee12cb01260e94385887f285ef9389"}, + {file = "librt-0.7.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e40d20ae1722d6b8ea6acf4597e789604649dcd9c295eb7361a28225bc2e9e12"}, + {file = "librt-0.7.7-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f2cb63c49bc96847c3bb8dca350970e4dcd19936f391cfdfd057dcb37c4fa97e"}, + {file = "librt-0.7.7-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f2f8dcf5ab9f80fb970c6fd780b398efb2f50c1962485eb8d3ab07788595a48"}, + {file = "librt-0.7.7-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a1f5cc41a570269d1be7a676655875e3a53de4992a9fa38efb7983e97cf73d7c"}, + {file = "librt-0.7.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ff1fb2dfef035549565a4124998fadcb7a3d4957131ddf004a56edeb029626b3"}, + {file = "librt-0.7.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ab2a2a9cd7d044e1a11ca64a86ad3361d318176924bbe5152fbc69f99be20b8c"}, + {file = "librt-0.7.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ad3fc2d859a709baf9dd9607bb72f599b1cfb8a39eafd41307d0c3c4766763cb"}, + {file = "librt-0.7.7-cp39-cp39-win32.whl", hash = "sha256:f83c971eb9d2358b6a18da51dc0ae00556ac7c73104dde16e9e14c15aaf685ca"}, + {file = "librt-0.7.7-cp39-cp39-win_amd64.whl", hash = "sha256:264720fc288c86039c091a4ad63419a5d7cabbf1c1c9933336a957ed2483e570"}, + {file = "librt-0.7.7.tar.gz", hash = "sha256:81d957b069fed1890953c3b9c3895c7689960f233eea9a1d9607f71ce7f00b2c"}, +] + [[package]] name = "markupsafe" version = "3.0.3" @@ -2213,68 +2384,68 @@ dev = ["meson-python (>=0.13.1,<0.17.0)", "numpy (>=1.25)", "pybind11 (>=2.6,!=2 [[package]] name = "matplotlib" -version = "3.10.7" +version = "3.10.8" description = "Python plotting package" optional = false python-versions = ">=3.10" groups = ["main", "examples"] markers = "python_version >= \"3.11\"" files = [ - {file = "matplotlib-3.10.7-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7ac81eee3b7c266dd92cee1cd658407b16c57eed08c7421fa354ed68234de380"}, - {file = "matplotlib-3.10.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:667ecd5d8d37813a845053d8f5bf110b534c3c9f30e69ebd25d4701385935a6d"}, - {file = "matplotlib-3.10.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc1c51b846aca49a5a8b44fbba6a92d583a35c64590ad9e1e950dc88940a4297"}, - {file = "matplotlib-3.10.7-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a11c2e9e72e7de09b7b72e62f3df23317c888299c875e2b778abf1eda8c0a42"}, - {file = "matplotlib-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f19410b486fdd139885ace124e57f938c1e6a3210ea13dd29cab58f5d4bc12c7"}, - {file = "matplotlib-3.10.7-cp310-cp310-win_amd64.whl", hash = "sha256:b498e9e4022f93de2d5a37615200ca01297ceebbb56fe4c833f46862a490f9e3"}, - {file = "matplotlib-3.10.7-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:53b492410a6cd66c7a471de6c924f6ede976e963c0f3097a3b7abfadddc67d0a"}, - {file = "matplotlib-3.10.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d9749313deb729f08207718d29c86246beb2ea3fdba753595b55901dee5d2fd6"}, - {file = "matplotlib-3.10.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2222c7ba2cbde7fe63032769f6eb7e83ab3227f47d997a8453377709b7fe3a5a"}, - {file = "matplotlib-3.10.7-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e91f61a064c92c307c5a9dc8c05dc9f8a68f0a3be199d9a002a0622e13f874a1"}, - {file = "matplotlib-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6f1851eab59ca082c95df5a500106bad73672645625e04538b3ad0f69471ffcc"}, - {file = "matplotlib-3.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:6516ce375109c60ceec579e699524e9d504cd7578506f01150f7a6bc174a775e"}, - {file = "matplotlib-3.10.7-cp311-cp311-win_arm64.whl", hash = "sha256:b172db79759f5f9bc13ef1c3ef8b9ee7b37b0247f987fbbbdaa15e4f87fd46a9"}, - {file = "matplotlib-3.10.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7a0edb7209e21840e8361e91ea84ea676658aa93edd5f8762793dec77a4a6748"}, - {file = "matplotlib-3.10.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c380371d3c23e0eadf8ebff114445b9f970aff2010198d498d4ab4c3b41eea4f"}, - {file = "matplotlib-3.10.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d5f256d49fea31f40f166a5e3131235a5d2f4b7f44520b1cf0baf1ce568ccff0"}, - {file = "matplotlib-3.10.7-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11ae579ac83cdf3fb72573bb89f70e0534de05266728740d478f0f818983c695"}, - {file = "matplotlib-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4c14b6acd16cddc3569a2d515cfdd81c7a68ac5639b76548cfc1a9e48b20eb65"}, - {file = "matplotlib-3.10.7-cp312-cp312-win_amd64.whl", hash = "sha256:0d8c32b7ea6fb80b1aeff5a2ceb3fb9778e2759e899d9beff75584714afcc5ee"}, - {file = "matplotlib-3.10.7-cp312-cp312-win_arm64.whl", hash = "sha256:5f3f6d315dcc176ba7ca6e74c7768fb7e4cf566c49cb143f6bc257b62e634ed8"}, - {file = "matplotlib-3.10.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1d9d3713a237970569156cfb4de7533b7c4eacdd61789726f444f96a0d28f57f"}, - {file = "matplotlib-3.10.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:37a1fea41153dd6ee061d21ab69c9cf2cf543160b1b85d89cd3d2e2a7902ca4c"}, - {file = "matplotlib-3.10.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b3c4ea4948d93c9c29dc01c0c23eef66f2101bf75158c291b88de6525c55c3d1"}, - {file = "matplotlib-3.10.7-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22df30ffaa89f6643206cf13877191c63a50e8f800b038bc39bee9d2d4957632"}, - {file = "matplotlib-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b69676845a0a66f9da30e87f48be36734d6748024b525ec4710be40194282c84"}, - {file = "matplotlib-3.10.7-cp313-cp313-win_amd64.whl", hash = "sha256:744991e0cc863dd669c8dc9136ca4e6e0082be2070b9d793cbd64bec872a6815"}, - {file = "matplotlib-3.10.7-cp313-cp313-win_arm64.whl", hash = "sha256:fba2974df0bf8ce3c995fa84b79cde38326e0f7b5409e7a3a481c1141340bcf7"}, - {file = "matplotlib-3.10.7-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:932c55d1fa7af4423422cb6a492a31cbcbdbe68fd1a9a3f545aa5e7a143b5355"}, - {file = "matplotlib-3.10.7-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e38c2d581d62ee729a6e144c47a71b3f42fb4187508dbbf4fe71d5612c3433b"}, - {file = "matplotlib-3.10.7-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:786656bb13c237bbcebcd402f65f44dd61ead60ee3deb045af429d889c8dbc67"}, - {file = "matplotlib-3.10.7-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09d7945a70ea43bf9248f4b6582734c2fe726723204a76eca233f24cffc7ef67"}, - {file = "matplotlib-3.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d0b181e9fa8daf1d9f2d4c547527b167cb8838fc587deabca7b5c01f97199e84"}, - {file = "matplotlib-3.10.7-cp313-cp313t-win_amd64.whl", hash = "sha256:31963603041634ce1a96053047b40961f7a29eb8f9a62e80cc2c0427aa1d22a2"}, - {file = "matplotlib-3.10.7-cp313-cp313t-win_arm64.whl", hash = "sha256:aebed7b50aa6ac698c90f60f854b47e48cd2252b30510e7a1feddaf5a3f72cbf"}, - {file = "matplotlib-3.10.7-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d883460c43e8c6b173fef244a2341f7f7c0e9725c7fe68306e8e44ed9c8fb100"}, - {file = "matplotlib-3.10.7-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:07124afcf7a6504eafcb8ce94091c5898bbdd351519a1beb5c45f7a38c67e77f"}, - {file = "matplotlib-3.10.7-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c17398b709a6cce3d9fdb1595c33e356d91c098cd9486cb2cc21ea2ea418e715"}, - {file = "matplotlib-3.10.7-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7146d64f561498764561e9cd0ed64fcf582e570fc519e6f521e2d0cfd43365e1"}, - {file = "matplotlib-3.10.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:90ad854c0a435da3104c01e2c6f0028d7e719b690998a2333d7218db80950722"}, - {file = "matplotlib-3.10.7-cp314-cp314-win_amd64.whl", hash = "sha256:4645fc5d9d20ffa3a39361fcdbcec731382763b623b72627806bf251b6388866"}, - {file = "matplotlib-3.10.7-cp314-cp314-win_arm64.whl", hash = "sha256:9257be2f2a03415f9105c486d304a321168e61ad450f6153d77c69504ad764bb"}, - {file = "matplotlib-3.10.7-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1e4bbad66c177a8fdfa53972e5ef8be72a5f27e6a607cec0d8579abd0f3102b1"}, - {file = "matplotlib-3.10.7-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d8eb7194b084b12feb19142262165832fc6ee879b945491d1c3d4660748020c4"}, - {file = "matplotlib-3.10.7-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4d41379b05528091f00e1728004f9a8d7191260f3862178b88e8fd770206318"}, - {file = "matplotlib-3.10.7-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4a74f79fafb2e177f240579bc83f0b60f82cc47d2f1d260f422a0627207008ca"}, - {file = "matplotlib-3.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:702590829c30aada1e8cef0568ddbffa77ca747b4d6e36c6d173f66e301f89cc"}, - {file = "matplotlib-3.10.7-cp314-cp314t-win_amd64.whl", hash = "sha256:f79d5de970fc90cd5591f60053aecfce1fcd736e0303d9f0bf86be649fa68fb8"}, - {file = "matplotlib-3.10.7-cp314-cp314t-win_arm64.whl", hash = "sha256:cb783436e47fcf82064baca52ce748af71725d0352e1d31564cbe9c95df92b9c"}, - {file = "matplotlib-3.10.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5c09cf8f2793f81368f49f118b6f9f937456362bee282eac575cca7f84cda537"}, - {file = "matplotlib-3.10.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:de66744b2bb88d5cd27e80dfc2ec9f0517d0a46d204ff98fe9e5f2864eb67657"}, - {file = "matplotlib-3.10.7-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:53cc80662dd197ece414dd5b66e07370201515a3eaf52e7c518c68c16814773b"}, - {file = "matplotlib-3.10.7-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:15112bcbaef211bd663fa935ec33313b948e214454d949b723998a43357b17b0"}, - {file = "matplotlib-3.10.7-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d2a959c640cdeecdd2ec3136e8ea0441da59bcaf58d67e9c590740addba2cb68"}, - {file = "matplotlib-3.10.7-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3886e47f64611046bc1db523a09dd0a0a6bed6081e6f90e13806dd1d1d1b5e91"}, - {file = "matplotlib-3.10.7.tar.gz", hash = "sha256:a06ba7e2a2ef9131c79c49e63dad355d2d878413a0376c1727c8b9335ff731c7"}, + {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] @@ -2311,14 +2482,14 @@ test = ["flake8", "nbdime", "nbval", "notebook", "pytest"] [[package]] name = "mistune" -version = "3.1.4" +version = "3.2.0" description = "A sane and fast Markdown parser with useful plugins and renderers" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "mistune-3.1.4-py3-none-any.whl", hash = "sha256:93691da911e5d9d2e23bc54472892aff676df27a75274962ff9edc210364266d"}, - {file = "mistune-3.1.4.tar.gz", hash = "sha256:b5a7f801d389f724ec702840c11d8fc48f2b33519102fc7ee739e8177b672164"}, + {file = "mistune-3.2.0-py3-none-any.whl", hash = "sha256:febdc629a3c78616b94393c6580551e0e34cc289987ec6c35ed3f4be42d0eee1"}, + {file = "mistune-3.2.0.tar.gz", hash = "sha256:708487c8a8cdd99c9d90eb3ed4c3ed961246ff78ac82f03418f5183ab70e398a"}, ] [package.dependencies] @@ -2358,53 +2529,54 @@ dill = ">=0.4.0" [[package]] name = "mypy" -version = "1.18.2" +version = "1.19.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "mypy-1.18.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c1eab0cf6294dafe397c261a75f96dc2c31bffe3b944faa24db5def4e2b0f77c"}, - {file = "mypy-1.18.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a780ca61fc239e4865968ebc5240bb3bf610ef59ac398de9a7421b54e4a207e"}, - {file = "mypy-1.18.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:448acd386266989ef11662ce3c8011fd2a7b632e0ec7d61a98edd8e27472225b"}, - {file = "mypy-1.18.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f9e171c465ad3901dc652643ee4bffa8e9fef4d7d0eece23b428908c77a76a66"}, - {file = "mypy-1.18.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:592ec214750bc00741af1f80cbf96b5013d81486b7bb24cb052382c19e40b428"}, - {file = "mypy-1.18.2-cp310-cp310-win_amd64.whl", hash = "sha256:7fb95f97199ea11769ebe3638c29b550b5221e997c63b14ef93d2e971606ebed"}, - {file = "mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:807d9315ab9d464125aa9fcf6d84fde6e1dc67da0b6f80e7405506b8ac72bc7f"}, - {file = "mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:776bb00de1778caf4db739c6e83919c1d85a448f71979b6a0edd774ea8399341"}, - {file = "mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1379451880512ffce14505493bd9fe469e0697543717298242574882cf8cdb8d"}, - {file = "mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1331eb7fd110d60c24999893320967594ff84c38ac6d19e0a76c5fd809a84c86"}, - {file = "mypy-1.18.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ca30b50a51e7ba93b00422e486cbb124f1c56a535e20eff7b2d6ab72b3b2e37"}, - {file = "mypy-1.18.2-cp311-cp311-win_amd64.whl", hash = "sha256:664dc726e67fa54e14536f6e1224bcfce1d9e5ac02426d2326e2bb4e081d1ce8"}, - {file = "mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34"}, - {file = "mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764"}, - {file = "mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893"}, - {file = "mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914"}, - {file = "mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a2afc0fa0b0e91b4599ddfe0f91e2c26c2b5a5ab263737e998d6817874c5f7c8"}, - {file = "mypy-1.18.2-cp312-cp312-win_amd64.whl", hash = "sha256:d8068d0afe682c7c4897c0f7ce84ea77f6de953262b12d07038f4d296d547074"}, - {file = "mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc"}, - {file = "mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e"}, - {file = "mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986"}, - {file = "mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d"}, - {file = "mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7ab28cc197f1dd77a67e1c6f35cd1f8e8b73ed2217e4fc005f9e6a504e46e7ba"}, - {file = "mypy-1.18.2-cp313-cp313-win_amd64.whl", hash = "sha256:0e2785a84b34a72ba55fb5daf079a1003a34c05b22238da94fcae2bbe46f3544"}, - {file = "mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:62f0e1e988ad41c2a110edde6c398383a889d95b36b3e60bcf155f5164c4fdce"}, - {file = "mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8795a039bab805ff0c1dfdb8cd3344642c2b99b8e439d057aba30850b8d3423d"}, - {file = "mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6ca1e64b24a700ab5ce10133f7ccd956a04715463d30498e64ea8715236f9c9c"}, - {file = "mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb"}, - {file = "mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075"}, - {file = "mypy-1.18.2-cp314-cp314-win_amd64.whl", hash = "sha256:749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf"}, - {file = "mypy-1.18.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:25a9c8fb67b00599f839cf472713f54249a62efd53a54b565eb61956a7e3296b"}, - {file = "mypy-1.18.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2b9c7e284ee20e7598d6f42e13ca40b4928e6957ed6813d1ab6348aa3f47133"}, - {file = "mypy-1.18.2-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6985ed057513e344e43a26cc1cd815c7a94602fb6a3130a34798625bc2f07b6"}, - {file = "mypy-1.18.2-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22f27105f1525ec024b5c630c0b9f36d5c1cc4d447d61fe51ff4bd60633f47ac"}, - {file = "mypy-1.18.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:030c52d0ea8144e721e49b1f68391e39553d7451f0c3f8a7565b59e19fcb608b"}, - {file = "mypy-1.18.2-cp39-cp39-win_amd64.whl", hash = "sha256:aa5e07ac1a60a253445797e42b8b2963c9675563a94f11291ab40718b016a7a0"}, - {file = "mypy-1.18.2-py3-none-any.whl", hash = "sha256:22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e"}, - {file = "mypy-1.18.2.tar.gz", hash = "sha256:06a398102a5f203d7477b2923dda3634c36727fa5c237d8f859ef90c42a9924b"}, + {file = "mypy-1.19.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec"}, + {file = "mypy-1.19.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b"}, + {file = "mypy-1.19.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6"}, + {file = "mypy-1.19.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74"}, + {file = "mypy-1.19.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1"}, + {file = "mypy-1.19.1-cp310-cp310-win_amd64.whl", hash = "sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac"}, + {file = "mypy-1.19.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288"}, + {file = "mypy-1.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab"}, + {file = "mypy-1.19.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6"}, + {file = "mypy-1.19.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331"}, + {file = "mypy-1.19.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925"}, + {file = "mypy-1.19.1-cp311-cp311-win_amd64.whl", hash = "sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042"}, + {file = "mypy-1.19.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1"}, + {file = "mypy-1.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e"}, + {file = "mypy-1.19.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2"}, + {file = "mypy-1.19.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8"}, + {file = "mypy-1.19.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a"}, + {file = "mypy-1.19.1-cp312-cp312-win_amd64.whl", hash = "sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13"}, + {file = "mypy-1.19.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250"}, + {file = "mypy-1.19.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b"}, + {file = "mypy-1.19.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e"}, + {file = "mypy-1.19.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef"}, + {file = "mypy-1.19.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75"}, + {file = "mypy-1.19.1-cp313-cp313-win_amd64.whl", hash = "sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd"}, + {file = "mypy-1.19.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1"}, + {file = "mypy-1.19.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718"}, + {file = "mypy-1.19.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b"}, + {file = "mypy-1.19.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045"}, + {file = "mypy-1.19.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957"}, + {file = "mypy-1.19.1-cp314-cp314-win_amd64.whl", hash = "sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f"}, + {file = "mypy-1.19.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7bcfc336a03a1aaa26dfce9fff3e287a3ba99872a157561cbfcebe67c13308e3"}, + {file = "mypy-1.19.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b7951a701c07ea584c4fe327834b92a30825514c868b1f69c30445093fdd9d5a"}, + {file = "mypy-1.19.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b13cfdd6c87fc3efb69ea4ec18ef79c74c3f98b4e5498ca9b85ab3b2c2329a67"}, + {file = "mypy-1.19.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f28f99c824ecebcdaa2e55d82953e38ff60ee5ec938476796636b86afa3956e"}, + {file = "mypy-1.19.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c608937067d2fc5a4dd1a5ce92fd9e1398691b8c5d012d66e1ddd430e9244376"}, + {file = "mypy-1.19.1-cp39-cp39-win_amd64.whl", hash = "sha256:409088884802d511ee52ca067707b90c883426bd95514e8cfda8281dc2effe24"}, + {file = "mypy-1.19.1-py3-none-any.whl", hash = "sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247"}, + {file = "mypy-1.19.1.tar.gz", hash = "sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba"}, ] [package.dependencies] +librt = {version = ">=0.6.2", markers = "platform_python_implementation != \"PyPy\""} mypy_extensions = ">=1.0.0" pathspec = ">=0.9.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} @@ -2436,6 +2608,7 @@ description = "A client library for executing notebooks. Formerly nbconvert's Ex optional = false python-versions = ">=3.9.0" groups = ["dev"] +markers = "python_version < \"3.11\"" files = [ {file = "nbclient-0.10.2-py3-none-any.whl", hash = "sha256:4ffee11e788b4a27fabeb7955547e4318a5298f34342a4bfd01f2e1faaeadc3d"}, {file = "nbclient-0.10.2.tar.gz", hash = "sha256:90b7fc6b810630db87a6d0c2250b1f0ab4cf4d3c27a299b0cde78a4ed3fd9193"}, @@ -2452,6 +2625,30 @@ 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 = "nbclient" +version = "0.10.4" +description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." +optional = false +python-versions = ">=3.10.0" +groups = ["dev"] +markers = "python_version >= \"3.11\"" +files = [ + {file = "nbclient-0.10.4-py3-none-any.whl", hash = "sha256:9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440"}, + {file = "nbclient-0.10.4.tar.gz", hash = "sha256:1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9"}, +] + +[package.dependencies] +jupyter-client = ">=6.1.12" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +nbformat = ">=5.1.3" +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 (>=9.0.1,<10)", "pytest-asyncio (>=1.3.0)", "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 (>=9.0.1,<10)", "pytest-asyncio (>=1.3.0)", "pytest-cov (>=4.0)", "testpath", "xmltodict"] + [[package]] name = "nbconvert" version = "7.16.6" @@ -2526,27 +2723,27 @@ files = [ [[package]] name = "notebook" -version = "7.4.7" +version = "7.5.1" description = "Jupyter Notebook - A web-based notebook environment for interactive computing" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "notebook-7.4.7-py3-none-any.whl", hash = "sha256:362b7c95527f7dd3c4c84d410b782872fd9c734fb2524c11dd92758527b6eda6"}, - {file = "notebook-7.4.7.tar.gz", hash = "sha256:3f0a04027dfcee8a876de48fba13ab77ec8c12f72f848a222ed7f5081b9e342a"}, + {file = "notebook-7.5.1-py3-none-any.whl", hash = "sha256:f4e2451c19910c33b88709b84537e11f6368c1cdff1aa0c43db701aea535dd44"}, + {file = "notebook-7.5.1.tar.gz", hash = "sha256:b2fb4cef4d47d08c33aecce1c6c6e84be05436fbd791f88fce8df9fbca088b75"}, ] [package.dependencies] jupyter-server = ">=2.4.0,<3" -jupyterlab = ">=4.4.9,<4.5" -jupyterlab-server = ">=2.27.1,<3" +jupyterlab = ">=4.5.1,<4.6" +jupyterlab-server = ">=2.28.0,<3" notebook-shim = ">=0.2,<0.3" tornado = ">=6.2.0" [package.extras] dev = ["hatch", "pre-commit"] docs = ["myst-parser", "nbsphinx", "pydata-sphinx-theme", "sphinx (>=1.3.6)", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["importlib-resources (>=5.0) ; python_version < \"3.10\"", "ipykernel", "jupyter-server[test] (>=2.4.0,<3)", "jupyterlab-server[test] (>=2.27.1,<3)", "nbval", "pytest (>=7.0)", "pytest-console-scripts", "pytest-timeout", "pytest-tornasync", "requests"] +test = ["importlib-resources (>=5.0) ; python_version < \"3.10\"", "ipykernel", "jupyter-server[test] (>=2.4.0,<3)", "jupyterlab-server[test] (>=2.28.0,<3)", "nbval", "pytest (>=7.0)", "pytest-console-scripts", "pytest-timeout", "pytest-tornasync", "requests"] [[package]] name = "notebook-shim" @@ -2745,87 +2942,85 @@ files = [ [[package]] name = "numpy" -version = "2.3.4" +version = "2.4.0" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.11" groups = ["main", "examples"] markers = "python_version >= \"3.11\"" files = [ - {file = "numpy-2.3.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e78aecd2800b32e8347ce49316d3eaf04aed849cd5b38e0af39f829a4e59f5eb"}, - {file = "numpy-2.3.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7fd09cc5d65bda1e79432859c40978010622112e9194e581e3415a3eccc7f43f"}, - {file = "numpy-2.3.4-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:1b219560ae2c1de48ead517d085bc2d05b9433f8e49d0955c82e8cd37bd7bf36"}, - {file = "numpy-2.3.4-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:bafa7d87d4c99752d07815ed7a2c0964f8ab311eb8168f41b910bd01d15b6032"}, - {file = "numpy-2.3.4-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36dc13af226aeab72b7abad501d370d606326a0029b9f435eacb3b8c94b8a8b7"}, - {file = "numpy-2.3.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7b2f9a18b5ff9824a6af80de4f37f4ec3c2aab05ef08f51c77a093f5b89adda"}, - {file = "numpy-2.3.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9984bd645a8db6ca15d850ff996856d8762c51a2239225288f08f9050ca240a0"}, - {file = "numpy-2.3.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:64c5825affc76942973a70acf438a8ab618dbd692b84cd5ec40a0a0509edc09a"}, - {file = "numpy-2.3.4-cp311-cp311-win32.whl", hash = "sha256:ed759bf7a70342f7817d88376eb7142fab9fef8320d6019ef87fae05a99874e1"}, - {file = "numpy-2.3.4-cp311-cp311-win_amd64.whl", hash = "sha256:faba246fb30ea2a526c2e9645f61612341de1a83fb1e0c5edf4ddda5a9c10996"}, - {file = "numpy-2.3.4-cp311-cp311-win_arm64.whl", hash = "sha256:4c01835e718bcebe80394fd0ac66c07cbb90147ebbdad3dcecd3f25de2ae7e2c"}, - {file = "numpy-2.3.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ef1b5a3e808bc40827b5fa2c8196151a4c5abe110e1726949d7abddfe5c7ae11"}, - {file = "numpy-2.3.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c2f91f496a87235c6aaf6d3f3d89b17dba64996abadccb289f48456cff931ca9"}, - {file = "numpy-2.3.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f77e5b3d3da652b474cc80a14084927a5e86a5eccf54ca8ca5cbd697bf7f2667"}, - {file = "numpy-2.3.4-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:8ab1c5f5ee40d6e01cbe96de5863e39b215a4d24e7d007cad56c7184fdf4aeef"}, - {file = "numpy-2.3.4-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77b84453f3adcb994ddbd0d1c5d11db2d6bda1a2b7fd5ac5bd4649d6f5dc682e"}, - {file = "numpy-2.3.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4121c5beb58a7f9e6dfdee612cb24f4df5cd4db6e8261d7f4d7450a997a65d6a"}, - {file = "numpy-2.3.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65611ecbb00ac9846efe04db15cbe6186f562f6bb7e5e05f077e53a599225d16"}, - {file = "numpy-2.3.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dabc42f9c6577bcc13001b8810d300fe814b4cfbe8a92c873f269484594f9786"}, - {file = "numpy-2.3.4-cp312-cp312-win32.whl", hash = "sha256:a49d797192a8d950ca59ee2d0337a4d804f713bb5c3c50e8db26d49666e351dc"}, - {file = "numpy-2.3.4-cp312-cp312-win_amd64.whl", hash = "sha256:985f1e46358f06c2a09921e8921e2c98168ed4ae12ccd6e5e87a4f1857923f32"}, - {file = "numpy-2.3.4-cp312-cp312-win_arm64.whl", hash = "sha256:4635239814149e06e2cb9db3dd584b2fa64316c96f10656983b8026a82e6e4db"}, - {file = "numpy-2.3.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c090d4860032b857d94144d1a9976b8e36709e40386db289aaf6672de2a81966"}, - {file = "numpy-2.3.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a13fc473b6db0be619e45f11f9e81260f7302f8d180c49a22b6e6120022596b3"}, - {file = "numpy-2.3.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:3634093d0b428e6c32c3a69b78e554f0cd20ee420dcad5a9f3b2a63762ce4197"}, - {file = "numpy-2.3.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:043885b4f7e6e232d7df4f51ffdef8c36320ee9d5f227b380ea636722c7ed12e"}, - {file = "numpy-2.3.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ee6a571d1e4f0ea6d5f22d6e5fbd6ed1dc2b18542848e1e7301bd190500c9d7"}, - {file = "numpy-2.3.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fc8a63918b04b8571789688b2780ab2b4a33ab44bfe8ccea36d3eba51228c953"}, - {file = "numpy-2.3.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:40cc556d5abbc54aabe2b1ae287042d7bdb80c08edede19f0c0afb36ae586f37"}, - {file = "numpy-2.3.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ecb63014bb7f4ce653f8be7f1df8cbc6093a5a2811211770f6606cc92b5a78fd"}, - {file = "numpy-2.3.4-cp313-cp313-win32.whl", hash = "sha256:e8370eb6925bb8c1c4264fec52b0384b44f675f191df91cbe0140ec9f0955646"}, - {file = "numpy-2.3.4-cp313-cp313-win_amd64.whl", hash = "sha256:56209416e81a7893036eea03abcb91c130643eb14233b2515c90dcac963fe99d"}, - {file = "numpy-2.3.4-cp313-cp313-win_arm64.whl", hash = "sha256:a700a4031bc0fd6936e78a752eefb79092cecad2599ea9c8039c548bc097f9bc"}, - {file = "numpy-2.3.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:86966db35c4040fdca64f0816a1c1dd8dbd027d90fca5a57e00e1ca4cd41b879"}, - {file = "numpy-2.3.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:838f045478638b26c375ee96ea89464d38428c69170360b23a1a50fa4baa3562"}, - {file = "numpy-2.3.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d7315ed1dab0286adca467377c8381cd748f3dc92235f22a7dfc42745644a96a"}, - {file = "numpy-2.3.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:84f01a4d18b2cc4ade1814a08e5f3c907b079c847051d720fad15ce37aa930b6"}, - {file = "numpy-2.3.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:817e719a868f0dacde4abdfc5c1910b301877970195db9ab6a5e2c4bd5b121f7"}, - {file = "numpy-2.3.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85e071da78d92a214212cacea81c6da557cab307f2c34b5f85b628e94803f9c0"}, - {file = "numpy-2.3.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2ec646892819370cf3558f518797f16597b4e4669894a2ba712caccc9da53f1f"}, - {file = "numpy-2.3.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:035796aaaddfe2f9664b9a9372f089cfc88bd795a67bd1bfe15e6e770934cf64"}, - {file = "numpy-2.3.4-cp313-cp313t-win32.whl", hash = "sha256:fea80f4f4cf83b54c3a051f2f727870ee51e22f0248d3114b8e755d160b38cfb"}, - {file = "numpy-2.3.4-cp313-cp313t-win_amd64.whl", hash = "sha256:15eea9f306b98e0be91eb344a94c0e630689ef302e10c2ce5f7e11905c704f9c"}, - {file = "numpy-2.3.4-cp313-cp313t-win_arm64.whl", hash = "sha256:b6c231c9c2fadbae4011ca5e7e83e12dc4a5072f1a1d85a0a7b3ed754d145a40"}, - {file = "numpy-2.3.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:81c3e6d8c97295a7360d367f9f8553973651b76907988bb6066376bc2252f24e"}, - {file = "numpy-2.3.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7c26b0b2bf58009ed1f38a641f3db4be8d960a417ca96d14e5b06df1506d41ff"}, - {file = "numpy-2.3.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:62b2198c438058a20b6704351b35a1d7db881812d8512d67a69c9de1f18ca05f"}, - {file = "numpy-2.3.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:9d729d60f8d53a7361707f4b68a9663c968882dd4f09e0d58c044c8bf5faee7b"}, - {file = "numpy-2.3.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd0c630cf256b0a7fd9d0a11c9413b42fef5101219ce6ed5a09624f5a65392c7"}, - {file = "numpy-2.3.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5e081bc082825f8b139f9e9fe42942cb4054524598aaeb177ff476cc76d09d2"}, - {file = "numpy-2.3.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:15fb27364ed84114438fff8aaf998c9e19adbeba08c0b75409f8c452a8692c52"}, - {file = "numpy-2.3.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:85d9fb2d8cd998c84d13a79a09cc0c1091648e848e4e6249b0ccd7f6b487fa26"}, - {file = "numpy-2.3.4-cp314-cp314-win32.whl", hash = "sha256:e73d63fd04e3a9d6bc187f5455d81abfad05660b212c8804bf3b407e984cd2bc"}, - {file = "numpy-2.3.4-cp314-cp314-win_amd64.whl", hash = "sha256:3da3491cee49cf16157e70f607c03a217ea6647b1cea4819c4f48e53d49139b9"}, - {file = "numpy-2.3.4-cp314-cp314-win_arm64.whl", hash = "sha256:6d9cd732068e8288dbe2717177320723ccec4fb064123f0caf9bbd90ab5be868"}, - {file = "numpy-2.3.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:22758999b256b595cf0b1d102b133bb61866ba5ceecf15f759623b64c020c9ec"}, - {file = "numpy-2.3.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9cb177bc55b010b19798dc5497d540dea67fd13a8d9e882b2dae71de0cf09eb3"}, - {file = "numpy-2.3.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0f2bcc76f1e05e5ab58893407c63d90b2029908fa41f9f1cc51eecce936c3365"}, - {file = "numpy-2.3.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dc20bde86802df2ed8397a08d793da0ad7a5fd4ea3ac85d757bf5dd4ad7c252"}, - {file = "numpy-2.3.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5e199c087e2aa71c8f9ce1cb7a8e10677dc12457e7cc1be4798632da37c3e86e"}, - {file = "numpy-2.3.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85597b2d25ddf655495e2363fe044b0ae999b75bc4d630dc0d886484b03a5eb0"}, - {file = "numpy-2.3.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04a69abe45b49c5955923cf2c407843d1c85013b424ae8a560bba16c92fe44a0"}, - {file = "numpy-2.3.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e1708fac43ef8b419c975926ce1eaf793b0c13b7356cfab6ab0dc34c0a02ac0f"}, - {file = "numpy-2.3.4-cp314-cp314t-win32.whl", hash = "sha256:863e3b5f4d9915aaf1b8ec79ae560ad21f0b8d5e3adc31e73126491bb86dee1d"}, - {file = "numpy-2.3.4-cp314-cp314t-win_amd64.whl", hash = "sha256:962064de37b9aef801d33bc579690f8bfe6c5e70e29b61783f60bcba838a14d6"}, - {file = "numpy-2.3.4-cp314-cp314t-win_arm64.whl", hash = "sha256:8b5a9a39c45d852b62693d9b3f3e0fe052541f804296ff401a72a1b60edafb29"}, - {file = "numpy-2.3.4-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:6e274603039f924c0fe5cb73438fa9246699c78a6df1bd3decef9ae592ae1c05"}, - {file = "numpy-2.3.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d149aee5c72176d9ddbc6803aef9c0f6d2ceeea7626574fc68518da5476fa346"}, - {file = "numpy-2.3.4-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:6d34ed9db9e6395bb6cd33286035f73a59b058169733a9db9f85e650b88df37e"}, - {file = "numpy-2.3.4-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:fdebe771ca06bb8d6abce84e51dca9f7921fe6ad34a0c914541b063e9a68928b"}, - {file = "numpy-2.3.4-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:957e92defe6c08211eb77902253b14fe5b480ebc5112bc741fd5e9cd0608f847"}, - {file = "numpy-2.3.4-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13b9062e4f5c7ee5c7e5be96f29ba71bc5a37fed3d1d77c37390ae00724d296d"}, - {file = "numpy-2.3.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:81b3a59793523e552c4a96109dde028aa4448ae06ccac5a76ff6532a85558a7f"}, - {file = "numpy-2.3.4.tar.gz", hash = "sha256:a7d018bfedb375a8d979ac758b120ba846a7fe764911a64465fd87b8729f4a6a"}, + {file = "numpy-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:316b2f2584682318539f0bcaca5a496ce9ca78c88066579ebd11fd06f8e4741e"}, + {file = "numpy-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2718c1de8504121714234b6f8241d0019450353276c88b9453c9c3d92e101db"}, + {file = "numpy-2.4.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:21555da4ec4a0c942520ead42c3b0dc9477441e085c42b0fbdd6a084869a6f6b"}, + {file = "numpy-2.4.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:413aa561266a4be2d06cd2b9665e89d9f54c543f418773076a76adcf2af08bc7"}, + {file = "numpy-2.4.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0feafc9e03128074689183031181fac0897ff169692d8492066e949041096548"}, + {file = "numpy-2.4.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8fdfed3deaf1928fb7667d96e0567cdf58c2b370ea2ee7e586aa383ec2cb346"}, + {file = "numpy-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e06a922a469cae9a57100864caf4f8a97a1026513793969f8ba5b63137a35d25"}, + {file = "numpy-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:927ccf5cd17c48f801f4ed43a7e5673a2724bd2171460be3e3894e6e332ef83a"}, + {file = "numpy-2.4.0-cp311-cp311-win32.whl", hash = "sha256:882567b7ae57c1b1a0250208cc21a7976d8cbcc49d5a322e607e6f09c9e0bd53"}, + {file = "numpy-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:8b986403023c8f3bf8f487c2e6186afda156174d31c175f747d8934dfddf3479"}, + {file = "numpy-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:3f3096405acc48887458bbf9f6814d43785ac7ba2a57ea6442b581dedbc60ce6"}, + {file = "numpy-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2a8b6bb8369abefb8bd1801b054ad50e02b3275c8614dc6e5b0373c305291037"}, + {file = "numpy-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e284ca13d5a8367e43734148622caf0b261b275673823593e3e3634a6490f83"}, + {file = "numpy-2.4.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:49ff32b09f5aa0cd30a20c2b39db3e669c845589f2b7fc910365210887e39344"}, + {file = "numpy-2.4.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:36cbfb13c152b1c7c184ddac43765db8ad672567e7bafff2cc755a09917ed2e6"}, + {file = "numpy-2.4.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35ddc8f4914466e6fc954c76527aa91aa763682a4f6d73249ef20b418fe6effb"}, + {file = "numpy-2.4.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc578891de1db95b2a35001b695451767b580bb45753717498213c5ff3c41d63"}, + {file = "numpy-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98e81648e0b36e325ab67e46b5400a7a6d4a22b8a7c8e8bbfe20e7db7906bf95"}, + {file = "numpy-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d57b5046c120561ba8fa8e4030fbb8b822f3063910fa901ffadf16e2b7128ad6"}, + {file = "numpy-2.4.0-cp312-cp312-win32.whl", hash = "sha256:92190db305a6f48734d3982f2c60fa30d6b5ee9bff10f2887b930d7b40119f4c"}, + {file = "numpy-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:680060061adb2d74ce352628cb798cfdec399068aa7f07ba9fb818b2b3305f98"}, + {file = "numpy-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:39699233bc72dd482da1415dcb06076e32f60eddc796a796c5fb6c5efce94667"}, + {file = "numpy-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a152d86a3ae00ba5f47b3acf3b827509fd0b6cb7d3259665e63dafbad22a75ea"}, + {file = "numpy-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:39b19251dec4de8ff8496cd0806cbe27bf0684f765abb1f4809554de93785f2d"}, + {file = "numpy-2.4.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:009bd0ea12d3c784b6639a8457537016ce5172109e585338e11334f6a7bb88ee"}, + {file = "numpy-2.4.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5fe44e277225fd3dff6882d86d3d447205d43532c3627313d17e754fb3905a0e"}, + {file = "numpy-2.4.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f935c4493eda9069851058fa0d9e39dbf6286be690066509305e52912714dbb2"}, + {file = "numpy-2.4.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8cfa5f29a695cb7438965e6c3e8d06e0416060cf0d709c1b1c1653a939bf5c2a"}, + {file = "numpy-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ba0cb30acd3ef11c94dc27fbfba68940652492bc107075e7ffe23057f9425681"}, + {file = "numpy-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:60e8c196cd82cbbd4f130b5290007e13e6de3eca79f0d4d38014769d96a7c475"}, + {file = "numpy-2.4.0-cp313-cp313-win32.whl", hash = "sha256:5f48cb3e88fbc294dc90e215d86fbaf1c852c63dbdb6c3a3e63f45c4b57f7344"}, + {file = "numpy-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:a899699294f28f7be8992853c0c60741f16ff199205e2e6cdca155762cbaa59d"}, + {file = "numpy-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:9198f447e1dc5647d07c9a6bbe2063cc0132728cc7175b39dbc796da5b54920d"}, + {file = "numpy-2.4.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74623f2ab5cc3f7c886add4f735d1031a1d2be4a4ae63c0546cfd74e7a31ddf6"}, + {file = "numpy-2.4.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:0804a8e4ab070d1d35496e65ffd3cf8114c136a2b81f61dfab0de4b218aacfd5"}, + {file = "numpy-2.4.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:02a2038eb27f9443a8b266a66911e926566b5a6ffd1a689b588f7f35b81e7dc3"}, + {file = "numpy-2.4.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1889b3a3f47a7b5bee16bc25a2145bd7cb91897f815ce3499db64c7458b6d91d"}, + {file = "numpy-2.4.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85eef4cb5625c47ee6425c58a3502555e10f45ee973da878ac8248ad58c136f3"}, + {file = "numpy-2.4.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6dc8b7e2f4eb184b37655195f421836cfae6f58197b67e3ffc501f1333d993fa"}, + {file = "numpy-2.4.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:44aba2f0cafd287871a495fb3163408b0bd25bbce135c6f621534a07f4f7875c"}, + {file = "numpy-2.4.0-cp313-cp313t-win32.whl", hash = "sha256:20c115517513831860c573996e395707aa9fb691eb179200125c250e895fcd93"}, + {file = "numpy-2.4.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b48e35f4ab6f6a7597c46e301126ceba4c44cd3280e3750f85db48b082624fa4"}, + {file = "numpy-2.4.0-cp313-cp313t-win_arm64.whl", hash = "sha256:4d1cfce39e511069b11e67cd0bd78ceff31443b7c9e5c04db73c7a19f572967c"}, + {file = "numpy-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c95eb6db2884917d86cde0b4d4cf31adf485c8ec36bf8696dd66fa70de96f36b"}, + {file = "numpy-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:65167da969cd1ec3a1df31cb221ca3a19a8aaa25370ecb17d428415e93c1935e"}, + {file = "numpy-2.4.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:3de19cfecd1465d0dcf8a5b5ea8b3155b42ed0b639dba4b71e323d74f2a3be5e"}, + {file = "numpy-2.4.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:6c05483c3136ac4c91b4e81903cb53a8707d316f488124d0398499a4f8e8ef51"}, + {file = "numpy-2.4.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36667db4d6c1cea79c8930ab72fadfb4060feb4bfe724141cd4bd064d2e5f8ce"}, + {file = "numpy-2.4.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9a818668b674047fd88c4cddada7ab8f1c298812783e8328e956b78dc4807f9f"}, + {file = "numpy-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1ee32359fb7543b7b7bd0b2f46294db27e29e7bbdf70541e81b190836cd83ded"}, + {file = "numpy-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e493962256a38f58283de033d8af176c5c91c084ea30f15834f7545451c42059"}, + {file = "numpy-2.4.0-cp314-cp314-win32.whl", hash = "sha256:6bbaebf0d11567fa8926215ae731e1d58e6ec28a8a25235b8a47405d301332db"}, + {file = "numpy-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:3d857f55e7fdf7c38ab96c4558c95b97d1c685be6b05c249f5fdafcbd6f9899e"}, + {file = "numpy-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:bb50ce5fb202a26fd5404620e7ef820ad1ab3558b444cb0b55beb7ef66cd2d63"}, + {file = "numpy-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:355354388cba60f2132df297e2d53053d4063f79077b67b481d21276d61fc4df"}, + {file = "numpy-2.4.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:1d8f9fde5f6dc1b6fc34df8162f3b3079365468703fee7f31d4e0cc8c63baed9"}, + {file = "numpy-2.4.0-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:e0434aa22c821f44eeb4c650b81c7fbdd8c0122c6c4b5a576a76d5a35625ecd9"}, + {file = "numpy-2.4.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40483b2f2d3ba7aad426443767ff5632ec3156ef09742b96913787d13c336471"}, + {file = "numpy-2.4.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9e6a7664ddd9746e20b7325351fe1a8408d0a2bf9c63b5e898290ddc8f09544"}, + {file = "numpy-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ecb0019d44f4cdb50b676c5d0cb4b1eae8e15d1ed3d3e6639f986fc92b2ec52c"}, + {file = "numpy-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d0ffd9e2e4441c96a9c91ec1783285d80bf835b677853fc2770a89d50c1e48ac"}, + {file = "numpy-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:77f0d13fa87036d7553bf81f0e1fe3ce68d14c9976c9851744e4d3e91127e95f"}, + {file = "numpy-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b1f5b45829ac1848893f0ddf5cb326110604d6df96cdc255b0bf9edd154104d4"}, + {file = "numpy-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:23a3e9d1a6f360267e8fbb38ba5db355a6a7e9be71d7fce7ab3125e88bb646c8"}, + {file = "numpy-2.4.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b54c83f1c0c0f1d748dca0af516062b8829d53d1f0c402be24b4257a9c48ada6"}, + {file = "numpy-2.4.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:aabb081ca0ec5d39591fc33018cd4b3f96e1a2dd6756282029986d00a785fba4"}, + {file = "numpy-2.4.0-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:8eafe7c36c8430b7794edeab3087dec7bf31d634d92f2af9949434b9d1964cba"}, + {file = "numpy-2.4.0-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:2f585f52b2baf07ff3356158d9268ea095e221371f1074fadea2f42544d58b4d"}, + {file = "numpy-2.4.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:32ed06d0fe9cae27d8fb5f400c63ccee72370599c75e683a6358dd3a4fb50aaf"}, + {file = "numpy-2.4.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:57c540ed8fb1f05cb997c6761cd56db72395b0d6985e90571ff660452ade4f98"}, + {file = "numpy-2.4.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:a39fb973a726e63223287adc6dafe444ce75af952d711e400f3bf2b36ef55a7b"}, + {file = "numpy-2.4.0.tar.gz", hash = "sha256:6e504f7b16118198f138ef31ba24d985b124c2c469fe8467007cf30fd992f934"}, ] [[package]] @@ -3027,218 +3222,232 @@ files = [ [package.dependencies] ptyprocess = ">=0.5" -[[package]] -name = "pickleshare" -version = "0.7.5" -description = "Tiny 'shelve'-like database with concurrency support" -optional = false -python-versions = "*" -groups = ["dev"] -markers = "python_version < \"3.11\"" -files = [ - {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, - {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, -] - [[package]] name = "pillow" -version = "10.4.0" +version = "11.3.0" description = "Python Imaging Library (Fork)" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["main", "examples"] markers = "python_version < \"3.11\"" files = [ - {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, - {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, - {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, - {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, - {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, - {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, - {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, - {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, - {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, - {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, - {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, - {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, - {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, - {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, - {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, - {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, - {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, - {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, - {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, - {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, - {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, - {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, - {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, - {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, - {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, - {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, - {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, - {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, - {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, - {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, - {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, - {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, - {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, - {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, - {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, - {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, - {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, - {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, - {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, - {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, - {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, - {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, + {file = "pillow-11.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860"}, + {file = "pillow-11.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad"}, + {file = "pillow-11.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0"}, + {file = "pillow-11.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b"}, + {file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50"}, + {file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae"}, + {file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9"}, + {file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e"}, + {file = "pillow-11.3.0-cp310-cp310-win32.whl", hash = "sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6"}, + {file = "pillow-11.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f"}, + {file = "pillow-11.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f"}, + {file = "pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722"}, + {file = "pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288"}, + {file = "pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d"}, + {file = "pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494"}, + {file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58"}, + {file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f"}, + {file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e"}, + {file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94"}, + {file = "pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0"}, + {file = "pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac"}, + {file = "pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd"}, + {file = "pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4"}, + {file = "pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69"}, + {file = "pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d"}, + {file = "pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6"}, + {file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7"}, + {file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024"}, + {file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809"}, + {file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d"}, + {file = "pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149"}, + {file = "pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d"}, + {file = "pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542"}, + {file = "pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd"}, + {file = "pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8"}, + {file = "pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f"}, + {file = "pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c"}, + {file = "pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd"}, + {file = "pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e"}, + {file = "pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1"}, + {file = "pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805"}, + {file = "pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8"}, + {file = "pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2"}, + {file = "pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b"}, + {file = "pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3"}, + {file = "pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51"}, + {file = "pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580"}, + {file = "pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e"}, + {file = "pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d"}, + {file = "pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced"}, + {file = "pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c"}, + {file = "pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8"}, + {file = "pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59"}, + {file = "pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe"}, + {file = "pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c"}, + {file = "pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788"}, + {file = "pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31"}, + {file = "pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e"}, + {file = "pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12"}, + {file = "pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a"}, + {file = "pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632"}, + {file = "pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673"}, + {file = "pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027"}, + {file = "pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77"}, + {file = "pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874"}, + {file = "pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a"}, + {file = "pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214"}, + {file = "pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635"}, + {file = "pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6"}, + {file = "pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae"}, + {file = "pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653"}, + {file = "pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6"}, + {file = "pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36"}, + {file = "pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b"}, + {file = "pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477"}, + {file = "pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50"}, + {file = "pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b"}, + {file = "pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12"}, + {file = "pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db"}, + {file = "pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa"}, + {file = "pillow-11.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:48d254f8a4c776de343051023eb61ffe818299eeac478da55227d96e241de53f"}, + {file = "pillow-11.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7aee118e30a4cf54fdd873bd3a29de51e29105ab11f9aad8c32123f58c8f8081"}, + {file = "pillow-11.3.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:23cff760a9049c502721bdb743a7cb3e03365fafcdfc2ef9784610714166e5a4"}, + {file = "pillow-11.3.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6359a3bc43f57d5b375d1ad54a0074318a0844d11b76abccf478c37c986d3cfc"}, + {file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:092c80c76635f5ecb10f3f83d76716165c96f5229addbd1ec2bdbbda7d496e06"}, + {file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cadc9e0ea0a2431124cde7e1697106471fc4c1da01530e679b2391c37d3fbb3a"}, + {file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6a418691000f2a418c9135a7cf0d797c1bb7d9a485e61fe8e7722845b95ef978"}, + {file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:97afb3a00b65cc0804d1c7abddbf090a81eaac02768af58cbdcaaa0a931e0b6d"}, + {file = "pillow-11.3.0-cp39-cp39-win32.whl", hash = "sha256:ea944117a7974ae78059fcc1800e5d3295172bb97035c0c1d9345fca1419da71"}, + {file = "pillow-11.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:e5c5858ad8ec655450a7c7df532e9842cf8df7cc349df7225c60d5d348c8aada"}, + {file = "pillow-11.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:6abdbfd3aea42be05702a8dd98832329c167ee84400a1d1f61ab11437f1717eb"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a"}, + {file = "pillow-11.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7"}, + {file = "pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8"}, + {file = "pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523"}, ] [package.extras] -docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] fpx = ["olefile"] mic = ["olefile"] -tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +test-arrow = ["pyarrow"] +tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "trove-classifiers (>=2024.10.12)"] typing = ["typing-extensions ; python_version < \"3.10\""] xmp = ["defusedxml"] [[package]] name = "pillow" -version = "12.0.0" +version = "12.1.0" description = "Python Imaging Library (fork)" optional = false python-versions = ">=3.10" groups = ["main", "examples"] markers = "python_version >= \"3.11\"" files = [ - {file = "pillow-12.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:3adfb466bbc544b926d50fe8f4a4e6abd8c6bffd28a26177594e6e9b2b76572b"}, - {file = "pillow-12.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1ac11e8ea4f611c3c0147424eae514028b5e9077dd99ab91e1bd7bc33ff145e1"}, - {file = "pillow-12.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d49e2314c373f4c2b39446fb1a45ed333c850e09d0c59ac79b72eb3b95397363"}, - {file = "pillow-12.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c7b2a63fd6d5246349f3d3f37b14430d73ee7e8173154461785e43036ffa96ca"}, - {file = "pillow-12.0.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d64317d2587c70324b79861babb9c09f71fbb780bad212018874b2c013d8600e"}, - {file = "pillow-12.0.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d77153e14b709fd8b8af6f66a3afbb9ed6e9fc5ccf0b6b7e1ced7b036a228782"}, - {file = "pillow-12.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:32ed80ea8a90ee3e6fa08c21e2e091bba6eda8eccc83dbc34c95169507a91f10"}, - {file = "pillow-12.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c828a1ae702fc712978bda0320ba1b9893d99be0badf2647f693cc01cf0f04fa"}, - {file = "pillow-12.0.0-cp310-cp310-win32.whl", hash = "sha256:bd87e140e45399c818fac4247880b9ce719e4783d767e030a883a970be632275"}, - {file = "pillow-12.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:455247ac8a4cfb7b9bc45b7e432d10421aea9fc2e74d285ba4072688a74c2e9d"}, - {file = "pillow-12.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:6ace95230bfb7cd79ef66caa064bbe2f2a1e63d93471c3a2e1f1348d9f22d6b7"}, - {file = "pillow-12.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0fd00cac9c03256c8b2ff58f162ebcd2587ad3e1f2e397eab718c47e24d231cc"}, - {file = "pillow-12.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3475b96f5908b3b16c47533daaa87380c491357d197564e0ba34ae75c0f3257"}, - {file = "pillow-12.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:110486b79f2d112cf6add83b28b627e369219388f64ef2f960fef9ebaf54c642"}, - {file = "pillow-12.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5269cc1caeedb67e6f7269a42014f381f45e2e7cd42d834ede3c703a1d915fe3"}, - {file = "pillow-12.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa5129de4e174daccbc59d0a3b6d20eaf24417d59851c07ebb37aeb02947987c"}, - {file = "pillow-12.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bee2a6db3a7242ea309aa7ee8e2780726fed67ff4e5b40169f2c940e7eb09227"}, - {file = "pillow-12.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:90387104ee8400a7b4598253b4c406f8958f59fcf983a6cea2b50d59f7d63d0b"}, - {file = "pillow-12.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc91a56697869546d1b8f0a3ff35224557ae7f881050e99f615e0119bf934b4e"}, - {file = "pillow-12.0.0-cp311-cp311-win32.whl", hash = "sha256:27f95b12453d165099c84f8a8bfdfd46b9e4bda9e0e4b65f0635430027f55739"}, - {file = "pillow-12.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:b583dc9070312190192631373c6c8ed277254aa6e6084b74bdd0a6d3b221608e"}, - {file = "pillow-12.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:759de84a33be3b178a64c8ba28ad5c135900359e85fb662bc6e403ad4407791d"}, - {file = "pillow-12.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:53561a4ddc36facb432fae7a9d8afbfaf94795414f5cdc5fc52f28c1dca90371"}, - {file = "pillow-12.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:71db6b4c1653045dacc1585c1b0d184004f0d7e694c7b34ac165ca70c0838082"}, - {file = "pillow-12.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2fa5f0b6716fc88f11380b88b31fe591a06c6315e955c096c35715788b339e3f"}, - {file = "pillow-12.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:82240051c6ca513c616f7f9da06e871f61bfd7805f566275841af15015b8f98d"}, - {file = "pillow-12.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55f818bd74fe2f11d4d7cbc65880a843c4075e0ac7226bc1a23261dbea531953"}, - {file = "pillow-12.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b87843e225e74576437fd5b6a4c2205d422754f84a06942cfaf1dc32243e45a8"}, - {file = "pillow-12.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c607c90ba67533e1b2355b821fef6764d1dd2cbe26b8c1005ae84f7aea25ff79"}, - {file = "pillow-12.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:21f241bdd5080a15bc86d3466a9f6074a9c2c2b314100dd896ac81ee6db2f1ba"}, - {file = "pillow-12.0.0-cp312-cp312-win32.whl", hash = "sha256:dd333073e0cacdc3089525c7df7d39b211bcdf31fc2824e49d01c6b6187b07d0"}, - {file = "pillow-12.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9fe611163f6303d1619bbcb653540a4d60f9e55e622d60a3108be0d5b441017a"}, - {file = "pillow-12.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:7dfb439562f234f7d57b1ac6bc8fe7f838a4bd49c79230e0f6a1da93e82f1fad"}, - {file = "pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0869154a2d0546545cde61d1789a6524319fc1897d9ee31218eae7a60ccc5643"}, - {file = "pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a7921c5a6d31b3d756ec980f2f47c0cfdbce0fc48c22a39347a895f41f4a6ea4"}, - {file = "pillow-12.0.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1ee80a59f6ce048ae13cda1abf7fbd2a34ab9ee7d401c46be3ca685d1999a399"}, - {file = "pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5"}, - {file = "pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b"}, - {file = "pillow-12.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bde737cff1a975b70652b62d626f7785e0480918dece11e8fef3c0cf057351c3"}, - {file = "pillow-12.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a6597ff2b61d121172f5844b53f21467f7082f5fb385a9a29c01414463f93b07"}, - {file = "pillow-12.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b817e7035ea7f6b942c13aa03bb554fc44fea70838ea21f8eb31c638326584e"}, - {file = "pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344"}, - {file = "pillow-12.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e51b71417049ad6ab14c49608b4a24d8fb3fe605e5dfabfe523b58064dc3d27"}, - {file = "pillow-12.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d120c38a42c234dc9a8c5de7ceaaf899cf33561956acb4941653f8bdc657aa79"}, - {file = "pillow-12.0.0-cp313-cp313-win32.whl", hash = "sha256:4cc6b3b2efff105c6a1656cfe59da4fdde2cda9af1c5e0b58529b24525d0a098"}, - {file = "pillow-12.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905"}, - {file = "pillow-12.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:9f0b04c6b8584c2c193babcccc908b38ed29524b29dd464bc8801bf10d746a3a"}, - {file = "pillow-12.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7fa22993bac7b77b78cae22bad1e2a987ddf0d9015c63358032f84a53f23cdc3"}, - {file = "pillow-12.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f135c702ac42262573fe9714dfe99c944b4ba307af5eb507abef1667e2cbbced"}, - {file = "pillow-12.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c85de1136429c524e55cfa4e033b4a7940ac5c8ee4d9401cc2d1bf48154bbc7b"}, - {file = "pillow-12.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38df9b4bfd3db902c9c2bd369bcacaf9d935b2fff73709429d95cc41554f7b3d"}, - {file = "pillow-12.0.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d87ef5795da03d742bf49439f9ca4d027cde49c82c5371ba52464aee266699a"}, - {file = "pillow-12.0.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aff9e4d82d082ff9513bdd6acd4f5bd359f5b2c870907d2b0a9c5e10d40c88fe"}, - {file = "pillow-12.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8d8ca2b210ada074d57fcee40c30446c9562e542fc46aedc19baf758a93532ee"}, - {file = "pillow-12.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:99a7f72fb6249302aa62245680754862a44179b545ded638cf1fef59befb57ef"}, - {file = "pillow-12.0.0-cp313-cp313t-win32.whl", hash = "sha256:4078242472387600b2ce8d93ade8899c12bf33fa89e55ec89fe126e9d6d5d9e9"}, - {file = "pillow-12.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2c54c1a783d6d60595d3514f0efe9b37c8808746a66920315bfd34a938d7994b"}, - {file = "pillow-12.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:26d9f7d2b604cd23aba3e9faf795787456ac25634d82cd060556998e39c6fa47"}, - {file = "pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:beeae3f27f62308f1ddbcfb0690bf44b10732f2ef43758f169d5e9303165d3f9"}, - {file = "pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d4827615da15cd59784ce39d3388275ec093ae3ee8d7f0c089b76fa87af756c2"}, - {file = "pillow-12.0.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:3e42edad50b6909089750e65c91aa09aaf1e0a71310d383f11321b27c224ed8a"}, - {file = "pillow-12.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e5d8efac84c9afcb40914ab49ba063d94f5dbdf5066db4482c66a992f47a3a3b"}, - {file = "pillow-12.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:266cd5f2b63ff316d5a1bba46268e603c9caf5606d44f38c2873c380950576ad"}, - {file = "pillow-12.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58eea5ebe51504057dd95c5b77d21700b77615ab0243d8152793dc00eb4faf01"}, - {file = "pillow-12.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f13711b1a5ba512d647a0e4ba79280d3a9a045aaf7e0cc6fbe96b91d4cdf6b0c"}, - {file = "pillow-12.0.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6846bd2d116ff42cba6b646edf5bf61d37e5cbd256425fa089fee4ff5c07a99e"}, - {file = "pillow-12.0.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c98fa880d695de164b4135a52fd2e9cd7b7c90a9d8ac5e9e443a24a95ef9248e"}, - {file = "pillow-12.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa3ed2a29a9e9d2d488b4da81dcb54720ac3104a20bf0bd273f1e4648aff5af9"}, - {file = "pillow-12.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d034140032870024e6b9892c692fe2968493790dd57208b2c37e3fb35f6df3ab"}, - {file = "pillow-12.0.0-cp314-cp314-win32.whl", hash = "sha256:1b1b133e6e16105f524a8dec491e0586d072948ce15c9b914e41cdadd209052b"}, - {file = "pillow-12.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:8dc232e39d409036af549c86f24aed8273a40ffa459981146829a324e0848b4b"}, - {file = "pillow-12.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:d52610d51e265a51518692045e372a4c363056130d922a7351429ac9f27e70b0"}, - {file = "pillow-12.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1979f4566bb96c1e50a62d9831e2ea2d1211761e5662afc545fa766f996632f6"}, - {file = "pillow-12.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b2e4b27a6e15b04832fe9bf292b94b5ca156016bbc1ea9c2c20098a0320d6cf6"}, - {file = "pillow-12.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fb3096c30df99fd01c7bf8e544f392103d0795b9f98ba71a8054bcbf56b255f1"}, - {file = "pillow-12.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7438839e9e053ef79f7112c881cef684013855016f928b168b81ed5835f3e75e"}, - {file = "pillow-12.0.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d5c411a8eaa2299322b647cd932586b1427367fd3184ffbb8f7a219ea2041ca"}, - {file = "pillow-12.0.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7e091d464ac59d2c7ad8e7e08105eaf9dafbc3883fd7265ffccc2baad6ac925"}, - {file = "pillow-12.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:792a2c0be4dcc18af9d4a2dfd8a11a17d5e25274a1062b0ec1c2d79c76f3e7f8"}, - {file = "pillow-12.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:afbefa430092f71a9593a99ab6a4e7538bc9eabbf7bf94f91510d3503943edc4"}, - {file = "pillow-12.0.0-cp314-cp314t-win32.whl", hash = "sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52"}, - {file = "pillow-12.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a"}, - {file = "pillow-12.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b22bd8c974942477156be55a768f7aa37c46904c175be4e158b6a86e3a6b7ca8"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:805ebf596939e48dbb2e4922a1d3852cfc25c38160751ce02da93058b48d252a"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cae81479f77420d217def5f54b5b9d279804d17e982e0f2fa19b1d1e14ab5197"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeaefa96c768fc66818730b952a862235d68825c178f1b3ffd4efd7ad2edcb7c"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09f2d0abef9e4e2f349305a4f8cc784a8a6c2f58a8c4892eea13b10a943bd26e"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bdee52571a343d721fb2eb3b090a82d959ff37fc631e3f70422e0c2e029f3e76"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b290fd8aa38422444d4b50d579de197557f182ef1068b75f5aa8558638b8d0a5"}, - {file = "pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353"}, + {file = "pillow-12.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:fb125d860738a09d363a88daa0f59c4533529a90e564785e20fe875b200b6dbd"}, + {file = "pillow-12.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cad302dc10fac357d3467a74a9561c90609768a6f73a1923b0fd851b6486f8b0"}, + {file = "pillow-12.1.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a40905599d8079e09f25027423aed94f2823adaf2868940de991e53a449e14a8"}, + {file = "pillow-12.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:92a7fe4225365c5e3a8e598982269c6d6698d3e783b3b1ae979e7819f9cd55c1"}, + {file = "pillow-12.1.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f10c98f49227ed8383d28174ee95155a675c4ed7f85e2e573b04414f7e371bda"}, + {file = "pillow-12.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8637e29d13f478bc4f153d8daa9ffb16455f0a6cb287da1b432fdad2bfbd66c7"}, + {file = "pillow-12.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:21e686a21078b0f9cb8c8a961d99e6a4ddb88e0fc5ea6e130172ddddc2e5221a"}, + {file = "pillow-12.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2415373395a831f53933c23ce051021e79c8cd7979822d8cc478547a3f4da8ef"}, + {file = "pillow-12.1.0-cp310-cp310-win32.whl", hash = "sha256:e75d3dba8fc1ddfec0cd752108f93b83b4f8d6ab40e524a95d35f016b9683b09"}, + {file = "pillow-12.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:64efdf00c09e31efd754448a383ea241f55a994fd079866b92d2bbff598aad91"}, + {file = "pillow-12.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:f188028b5af6b8fb2e9a76ac0f841a575bd1bd396e46ef0840d9b88a48fdbcea"}, + {file = "pillow-12.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:a83e0850cb8f5ac975291ebfc4170ba481f41a28065277f7f735c202cd8e0af3"}, + {file = "pillow-12.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b6e53e82ec2db0717eabb276aa56cf4e500c9a7cec2c2e189b55c24f65a3e8c0"}, + {file = "pillow-12.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:40a8e3b9e8773876d6e30daed22f016509e3987bab61b3b7fe309d7019a87451"}, + {file = "pillow-12.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:800429ac32c9b72909c671aaf17ecd13110f823ddb7db4dfef412a5587c2c24e"}, + {file = "pillow-12.1.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b022eaaf709541b391ee069f0022ee5b36c709df71986e3f7be312e46f42c84"}, + {file = "pillow-12.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f345e7bc9d7f368887c712aa5054558bad44d2a301ddf9248599f4161abc7c0"}, + {file = "pillow-12.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d70347c8a5b7ccd803ec0c85c8709f036e6348f1e6a5bf048ecd9c64d3550b8b"}, + {file = "pillow-12.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1fcc52d86ce7a34fd17cb04e87cfdb164648a3662a6f20565910a99653d66c18"}, + {file = "pillow-12.1.0-cp311-cp311-win32.whl", hash = "sha256:3ffaa2f0659e2f740473bcf03c702c39a8d4b2b7ffc629052028764324842c64"}, + {file = "pillow-12.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:806f3987ffe10e867bab0ddad45df1148a2b98221798457fa097ad85d6e8bc75"}, + {file = "pillow-12.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:9f5fefaca968e700ad1a4a9de98bf0869a94e397fe3524c4c9450c1445252304"}, + {file = "pillow-12.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a332ac4ccb84b6dde65dbace8431f3af08874bf9770719d32a635c4ef411b18b"}, + {file = "pillow-12.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:907bfa8a9cb790748a9aa4513e37c88c59660da3bcfffbd24a7d9e6abf224551"}, + {file = "pillow-12.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:efdc140e7b63b8f739d09a99033aa430accce485ff78e6d311973a67b6bf3208"}, + {file = "pillow-12.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bef9768cab184e7ae6e559c032e95ba8d07b3023c289f79a2bd36e8bf85605a5"}, + {file = "pillow-12.1.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:742aea052cf5ab5034a53c3846165bc3ce88d7c38e954120db0ab867ca242661"}, + {file = "pillow-12.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a6dfc2af5b082b635af6e08e0d1f9f1c4e04d17d4e2ca0ef96131e85eda6eb17"}, + {file = "pillow-12.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:609e89d9f90b581c8d16358c9087df76024cf058fa693dd3e1e1620823f39670"}, + {file = "pillow-12.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:43b4899cfd091a9693a1278c4982f3e50f7fb7cff5153b05174b4afc9593b616"}, + {file = "pillow-12.1.0-cp312-cp312-win32.whl", hash = "sha256:aa0c9cc0b82b14766a99fbe6084409972266e82f459821cd26997a488a7261a7"}, + {file = "pillow-12.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:d70534cea9e7966169ad29a903b99fc507e932069a881d0965a1a84bb57f6c6d"}, + {file = "pillow-12.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:65b80c1ee7e14a87d6a068dd3b0aea268ffcabfe0498d38661b00c5b4b22e74c"}, + {file = "pillow-12.1.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7b5dd7cbae20285cdb597b10eb5a2c13aa9de6cde9bb64a3c1317427b1db1ae1"}, + {file = "pillow-12.1.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:29a4cef9cb672363926f0470afc516dbf7305a14d8c54f7abbb5c199cd8f8179"}, + {file = "pillow-12.1.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:681088909d7e8fa9e31b9799aaa59ba5234c58e5e4f1951b4c4d1082a2e980e0"}, + {file = "pillow-12.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:983976c2ab753166dc66d36af6e8ec15bb511e4a25856e2227e5f7e00a160587"}, + {file = "pillow-12.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:db44d5c160a90df2d24a24760bbd37607d53da0b34fb546c4c232af7192298ac"}, + {file = "pillow-12.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6b7a9d1db5dad90e2991645874f708e87d9a3c370c243c2d7684d28f7e133e6b"}, + {file = "pillow-12.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6258f3260986990ba2fa8a874f8b6e808cf5abb51a94015ca3dc3c68aa4f30ea"}, + {file = "pillow-12.1.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e115c15e3bc727b1ca3e641a909f77f8ca72a64fff150f666fcc85e57701c26c"}, + {file = "pillow-12.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6741e6f3074a35e47c77b23a4e4f2d90db3ed905cb1c5e6e0d49bff2045632bc"}, + {file = "pillow-12.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:935b9d1aed48fcfb3f838caac506f38e29621b44ccc4f8a64d575cb1b2a88644"}, + {file = "pillow-12.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5fee4c04aad8932da9f8f710af2c1a15a83582cfb884152a9caa79d4efcdbf9c"}, + {file = "pillow-12.1.0-cp313-cp313-win32.whl", hash = "sha256:a786bf667724d84aa29b5db1c61b7bfdde380202aaca12c3461afd6b71743171"}, + {file = "pillow-12.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:461f9dfdafa394c59cd6d818bdfdbab4028b83b02caadaff0ffd433faf4c9a7a"}, + {file = "pillow-12.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:9212d6b86917a2300669511ed094a9406888362e085f2431a7da985a6b124f45"}, + {file = "pillow-12.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:00162e9ca6d22b7c3ee8e61faa3c3253cd19b6a37f126cad04f2f88b306f557d"}, + {file = "pillow-12.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7d6daa89a00b58c37cb1747ec9fb7ac3bc5ffd5949f5888657dfddde6d1312e0"}, + {file = "pillow-12.1.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e2479c7f02f9d505682dc47df8c0ea1fc5e264c4d1629a5d63fe3e2334b89554"}, + {file = "pillow-12.1.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f188d580bd870cda1e15183790d1cc2fa78f666e76077d103edf048eed9c356e"}, + {file = "pillow-12.1.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0fde7ec5538ab5095cc02df38ee99b0443ff0e1c847a045554cf5f9af1f4aa82"}, + {file = "pillow-12.1.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ed07dca4a8464bada6139ab38f5382f83e5f111698caf3191cb8dbf27d908b4"}, + {file = "pillow-12.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f45bd71d1fa5e5749587613037b172e0b3b23159d1c00ef2fc920da6f470e6f0"}, + {file = "pillow-12.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:277518bf4fe74aa91489e1b20577473b19ee70fb97c374aa50830b279f25841b"}, + {file = "pillow-12.1.0-cp313-cp313t-win32.whl", hash = "sha256:7315f9137087c4e0ee73a761b163fc9aa3b19f5f606a7fc08d83fd3e4379af65"}, + {file = "pillow-12.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:0ddedfaa8b5f0b4ffbc2fa87b556dc59f6bb4ecb14a53b33f9189713ae8053c0"}, + {file = "pillow-12.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:80941e6d573197a0c28f394753de529bb436b1ca990ed6e765cf42426abc39f8"}, + {file = "pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:5cb7bc1966d031aec37ddb9dcf15c2da5b2e9f7cc3ca7c54473a20a927e1eb91"}, + {file = "pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:97e9993d5ed946aba26baf9c1e8cf18adbab584b99f452ee72f7ee8acb882796"}, + {file = "pillow-12.1.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:414b9a78e14ffeb98128863314e62c3f24b8a86081066625700b7985b3f529bd"}, + {file = "pillow-12.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e6bdb408f7c9dd2a5ff2b14a3b0bb6d4deb29fb9961e6eb3ae2031ae9a5cec13"}, + {file = "pillow-12.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3413c2ae377550f5487991d444428f1a8ae92784aac79caa8b1e3b89b175f77e"}, + {file = "pillow-12.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e5dcbe95016e88437ecf33544ba5db21ef1b8dd6e1b434a2cb2a3d605299e643"}, + {file = "pillow-12.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d0a7735df32ccbcc98b98a1ac785cc4b19b580be1bdf0aeb5c03223220ea09d5"}, + {file = "pillow-12.1.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c27407a2d1b96774cbc4a7594129cc027339fd800cd081e44497722ea1179de"}, + {file = "pillow-12.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15c794d74303828eaa957ff8070846d0efe8c630901a1c753fdc63850e19ecd9"}, + {file = "pillow-12.1.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c990547452ee2800d8506c4150280757f88532f3de2a58e3022e9b179107862a"}, + {file = "pillow-12.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b63e13dd27da389ed9475b3d28510f0f954bca0041e8e551b2a4eb1eab56a39a"}, + {file = "pillow-12.1.0-cp314-cp314-win32.whl", hash = "sha256:1a949604f73eb07a8adab38c4fe50791f9919344398bdc8ac6b307f755fc7030"}, + {file = "pillow-12.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:4f9f6a650743f0ddee5593ac9e954ba1bdbc5e150bc066586d4f26127853ab94"}, + {file = "pillow-12.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:808b99604f7873c800c4840f55ff389936ef1948e4e87645eaf3fccbc8477ac4"}, + {file = "pillow-12.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc11908616c8a283cf7d664f77411a5ed2a02009b0097ff8abbba5e79128ccf2"}, + {file = "pillow-12.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:896866d2d436563fa2a43a9d72f417874f16b5545955c54a64941e87c1376c61"}, + {file = "pillow-12.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8e178e3e99d3c0ea8fc64b88447f7cac8ccf058af422a6cedc690d0eadd98c51"}, + {file = "pillow-12.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:079af2fb0c599c2ec144ba2c02766d1b55498e373b3ac64687e43849fbbef5bc"}, + {file = "pillow-12.1.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bdec5e43377761c5dbca620efb69a77f6855c5a379e32ac5b158f54c84212b14"}, + {file = "pillow-12.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:565c986f4b45c020f5421a4cea13ef294dde9509a8577f29b2fc5edc7587fff8"}, + {file = "pillow-12.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:43aca0a55ce1eefc0aefa6253661cb54571857b1a7b2964bd8a1e3ef4b729924"}, + {file = "pillow-12.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0deedf2ea233722476b3a81e8cdfbad786f7adbed5d848469fa59fe52396e4ef"}, + {file = "pillow-12.1.0-cp314-cp314t-win32.whl", hash = "sha256:b17fbdbe01c196e7e159aacb889e091f28e61020a8abeac07b68079b6e626988"}, + {file = "pillow-12.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27b9baecb428899db6c0de572d6d305cfaf38ca1596b5c0542a5182e3e74e8c6"}, + {file = "pillow-12.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:f61333d817698bdcdd0f9d7793e365ac3d2a21c1f1eb02b32ad6aefb8d8ea831"}, + {file = "pillow-12.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ca94b6aac0d7af2a10ba08c0f888b3d5114439b6b3ef39968378723622fed377"}, + {file = "pillow-12.1.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:351889afef0f485b84078ea40fe33727a0492b9af3904661b0abbafee0355b72"}, + {file = "pillow-12.1.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb0984b30e973f7e2884362b7d23d0a348c7143ee559f38ef3eaab640144204c"}, + {file = "pillow-12.1.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:84cabc7095dd535ca934d57e9ce2a72ffd216e435a84acb06b2277b1de2689bd"}, + {file = "pillow-12.1.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53d8b764726d3af1a138dd353116f774e3862ec7e3794e0c8781e30db0f35dfc"}, + {file = "pillow-12.1.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5da841d81b1a05ef940a8567da92decaa15bc4d7dedb540a8c219ad83d91808a"}, + {file = "pillow-12.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:75af0b4c229ac519b155028fa1be632d812a519abba9b46b20e50c6caa184f19"}, + {file = "pillow-12.1.0.tar.gz", hash = "sha256:5c5ae0a06e9ea030ab786b0251b32c7e4ce10e58d983c0d5c56029455180b5b9"}, ] [package.extras] @@ -3251,33 +3460,33 @@ xmp = ["defusedxml"] [[package]] name = "platformdirs" -version = "4.3.6" +version = "4.4.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] markers = "python_version < \"3.11\"" files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, + {file = "platformdirs-4.4.0-py3-none-any.whl", hash = "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85"}, + {file = "platformdirs-4.4.0.tar.gz", hash = "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf"}, ] [package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.4)", "pytest-cov (>=6)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.14.1)"] [[package]] name = "platformdirs" -version = "4.5.0" +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"] markers = "python_version >= \"3.11\"" files = [ - {file = "platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3"}, - {file = "platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312"}, + {file = "platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31"}, + {file = "platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda"}, ] [package.extras] @@ -3397,36 +3606,38 @@ wcwidth = "*" [[package]] name = "psutil" -version = "7.1.2" +version = "7.2.1" description = "Cross-platform lib for process and system monitoring." optional = false python-versions = ">=3.6" groups = ["dev"] files = [ - {file = "psutil-7.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0cc5c6889b9871f231ed5455a9a02149e388fffcb30b607fb7a8896a6d95f22e"}, - {file = "psutil-7.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8e9e77a977208d84aa363a4a12e0f72189d58bbf4e46b49aae29a2c6e93ef206"}, - {file = "psutil-7.1.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d9623a5e4164d2220ecceb071f4b333b3c78866141e8887c072129185f41278"}, - {file = "psutil-7.1.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:364b1c10fe4ed59c89ec49e5f1a70da353b27986fa8233b4b999df4742a5ee2f"}, - {file = "psutil-7.1.2-cp313-cp313t-win_amd64.whl", hash = "sha256:f101ef84de7e05d41310e3ccbdd65a6dd1d9eed85e8aaf0758405d022308e204"}, - {file = "psutil-7.1.2-cp313-cp313t-win_arm64.whl", hash = "sha256:20c00824048a95de67f00afedc7b08b282aa08638585b0206a9fb51f28f1a165"}, - {file = "psutil-7.1.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:e09cfe92aa8e22b1ec5e2d394820cf86c5dff6367ac3242366485dfa874d43bc"}, - {file = "psutil-7.1.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fa6342cf859c48b19df3e4aa170e4cfb64aadc50b11e06bb569c6c777b089c9e"}, - {file = "psutil-7.1.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:625977443498ee7d6c1e63e93bacca893fd759a66c5f635d05e05811d23fb5ee"}, - {file = "psutil-7.1.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a24bcd7b7f2918d934af0fb91859f621b873d6aa81267575e3655cd387572a7"}, - {file = "psutil-7.1.2-cp314-cp314t-win_amd64.whl", hash = "sha256:329f05610da6380982e6078b9d0881d9ab1e9a7eb7c02d833bfb7340aa634e31"}, - {file = "psutil-7.1.2-cp314-cp314t-win_arm64.whl", hash = "sha256:7b04c29e3c0c888e83ed4762b70f31e65c42673ea956cefa8ced0e31e185f582"}, - {file = "psutil-7.1.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c9ba5c19f2d46203ee8c152c7b01df6eec87d883cfd8ee1af2ef2727f6b0f814"}, - {file = "psutil-7.1.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:2a486030d2fe81bec023f703d3d155f4823a10a47c36784c84f1cc7f8d39bedb"}, - {file = "psutil-7.1.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3efd8fc791492e7808a51cb2b94889db7578bfaea22df931424f874468e389e3"}, - {file = "psutil-7.1.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e2aeb9b64f481b8eabfc633bd39e0016d4d8bbcd590d984af764d80bf0851b8a"}, - {file = "psutil-7.1.2-cp37-abi3-win_amd64.whl", hash = "sha256:8e17852114c4e7996fe9da4745c2bdef001ebbf2f260dec406290e66628bdb91"}, - {file = "psutil-7.1.2-cp37-abi3-win_arm64.whl", hash = "sha256:3e988455e61c240cc879cb62a008c2699231bf3e3d061d7fce4234463fd2abb4"}, - {file = "psutil-7.1.2.tar.gz", hash = "sha256:aa225cdde1335ff9684708ee8c72650f6598d5ed2114b9a7c5802030b1785018"}, + {file = "psutil-7.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ba9f33bb525b14c3ea563b2fd521a84d2fa214ec59e3e6a2858f78d0844dd60d"}, + {file = "psutil-7.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:81442dac7abfc2f4f4385ea9e12ddf5a796721c0f6133260687fec5c3780fa49"}, + {file = "psutil-7.2.1-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ea46c0d060491051d39f0d2cff4f98d5c72b288289f57a21556cc7d504db37fc"}, + {file = "psutil-7.2.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35630d5af80d5d0d49cfc4d64c1c13838baf6717a13effb35869a5919b854cdf"}, + {file = "psutil-7.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:923f8653416604e356073e6e0bccbe7c09990acef442def2f5640dd0faa9689f"}, + {file = "psutil-7.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:cfbe6b40ca48019a51827f20d830887b3107a74a79b01ceb8cc8de4ccb17b672"}, + {file = "psutil-7.2.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:494c513ccc53225ae23eec7fe6e1482f1b8a44674241b54561f755a898650679"}, + {file = "psutil-7.2.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3fce5f92c22b00cdefd1645aa58ab4877a01679e901555067b1bd77039aa589f"}, + {file = "psutil-7.2.1-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93f3f7b0bb07711b49626e7940d6fe52aa9940ad86e8f7e74842e73189712129"}, + {file = "psutil-7.2.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d34d2ca888208eea2b5c68186841336a7f5e0b990edec929be909353a202768a"}, + {file = "psutil-7.2.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2ceae842a78d1603753561132d5ad1b2f8a7979cb0c283f5b52fb4e6e14b1a79"}, + {file = "psutil-7.2.1-cp314-cp314t-win_arm64.whl", hash = "sha256:08a2f175e48a898c8eb8eace45ce01777f4785bc744c90aa2cc7f2fa5462a266"}, + {file = "psutil-7.2.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b2e953fcfaedcfbc952b44744f22d16575d3aa78eb4f51ae74165b4e96e55f42"}, + {file = "psutil-7.2.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:05cc68dbb8c174828624062e73078e7e35406f4ca2d0866c272c2410d8ef06d1"}, + {file = "psutil-7.2.1-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e38404ca2bb30ed7267a46c02f06ff842e92da3bb8c5bfdadbd35a5722314d8"}, + {file = "psutil-7.2.1-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab2b98c9fc19f13f59628d94df5cc4cc4844bc572467d113a8b517d634e362c6"}, + {file = "psutil-7.2.1-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f78baafb38436d5a128f837fab2d92c276dfb48af01a240b861ae02b2413ada8"}, + {file = "psutil-7.2.1-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:99a4cd17a5fdd1f3d014396502daa70b5ec21bf4ffe38393e152f8e449757d67"}, + {file = "psutil-7.2.1-cp37-abi3-win_amd64.whl", hash = "sha256:b1b0671619343aa71c20ff9767eced0483e4fc9e1f489d50923738caf6a03c17"}, + {file = "psutil-7.2.1-cp37-abi3-win_arm64.whl", hash = "sha256:0d67c1822c355aa6f7314d92018fb4268a76668a536f133599b91edd48759442"}, + {file = "psutil-7.2.1.tar.gz", hash = "sha256:f7583aec590485b43ca601dd9cea0dcd65bd7bb21d30ef4ddbf4ea6b5ed1bdd3"}, ] [package.extras] -dev = ["abi3audit", "black", "check-manifest", "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\""] +dev = ["abi3audit", "black", "check-manifest", "coverage", "packaging", "psleak", "pylint", "pyperf", "pypinfo", "pytest", "pytest-cov", "pytest-instafail", "pytest-xdist", "requests", "rstcheck", "ruff", "setuptools", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "validate-pyproject[all]", "virtualenv", "vulture", "wheel"] +test = ["psleak", "pytest", "pytest-instafail", "pytest-xdist", "setuptools"] [[package]] name = "ptyprocess" @@ -3486,14 +3697,14 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pyparsing" -version = "3.2.5" +version = "3.3.1" description = "pyparsing - Classes and methods to define and execute parsing grammars" optional = false python-versions = ">=3.9" groups = ["main", "examples"] files = [ - {file = "pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e"}, - {file = "pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6"}, + {file = "pyparsing-3.3.1-py3-none-any.whl", hash = "sha256:023b5e7e5520ad96642e2c6db4cb683d3970bd640cdf7115049a6e9c3682df82"}, + {file = "pyparsing-3.3.1.tar.gz", hash = "sha256:47fad0f17ac1e2cad3de3b458570fbc9b03560aa029ed5e16ee5554da9a2251c"}, ] [package.extras] @@ -3824,20 +4035,21 @@ cffi = {version = "*", markers = "implementation_name == \"pypy\""} [[package]] name = "referencing" -version = "0.35.1" +version = "0.36.2" description = "JSON Referencing + Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] markers = "python_version < \"3.11\"" files = [ - {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, - {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, + {file = "referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0"}, + {file = "referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa"}, ] [package.dependencies] attrs = ">=22.2.0" rpds-py = ">=0.7.0" +typing-extensions = {version = ">=4.4.0", markers = "python_version < \"3.13\""} [[package]] name = "referencing" @@ -3926,242 +4138,294 @@ testing = ["pytest (>=8.3.5)"] [[package]] name = "rpds-py" -version = "0.20.1" +version = "0.27.1" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] markers = "python_version < \"3.11\"" files = [ - {file = "rpds_py-0.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a649dfd735fff086e8a9d0503a9f0c7d01b7912a333c7ae77e1515c08c146dad"}, - {file = "rpds_py-0.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f16bc1334853e91ddaaa1217045dd7be166170beec337576818461268a3de67f"}, - {file = "rpds_py-0.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14511a539afee6f9ab492b543060c7491c99924314977a55c98bfa2ee29ce78c"}, - {file = "rpds_py-0.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3ccb8ac2d3c71cda472b75af42818981bdacf48d2e21c36331b50b4f16930163"}, - {file = "rpds_py-0.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c142b88039b92e7e0cb2552e8967077e3179b22359e945574f5e2764c3953dcf"}, - {file = "rpds_py-0.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f19169781dddae7478a32301b499b2858bc52fc45a112955e798ee307e294977"}, - {file = "rpds_py-0.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13c56de6518e14b9bf6edde23c4c39dac5b48dcf04160ea7bce8fca8397cdf86"}, - {file = "rpds_py-0.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:925d176a549f4832c6f69fa6026071294ab5910e82a0fe6c6228fce17b0706bd"}, - {file = "rpds_py-0.20.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:78f0b6877bfce7a3d1ff150391354a410c55d3cdce386f862926a4958ad5ab7e"}, - {file = "rpds_py-0.20.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3dd645e2b0dcb0fd05bf58e2e54c13875847687d0b71941ad2e757e5d89d4356"}, - {file = "rpds_py-0.20.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4f676e21db2f8c72ff0936f895271e7a700aa1f8d31b40e4e43442ba94973899"}, - {file = "rpds_py-0.20.1-cp310-none-win32.whl", hash = "sha256:648386ddd1e19b4a6abab69139b002bc49ebf065b596119f8f37c38e9ecee8ff"}, - {file = "rpds_py-0.20.1-cp310-none-win_amd64.whl", hash = "sha256:d9ecb51120de61e4604650666d1f2b68444d46ae18fd492245a08f53ad2b7711"}, - {file = "rpds_py-0.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:762703bdd2b30983c1d9e62b4c88664df4a8a4d5ec0e9253b0231171f18f6d75"}, - {file = "rpds_py-0.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0b581f47257a9fce535c4567782a8976002d6b8afa2c39ff616edf87cbeff712"}, - {file = "rpds_py-0.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:842c19a6ce894493563c3bd00d81d5100e8e57d70209e84d5491940fdb8b9e3a"}, - {file = "rpds_py-0.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42cbde7789f5c0bcd6816cb29808e36c01b960fb5d29f11e052215aa85497c93"}, - {file = "rpds_py-0.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c8e9340ce5a52f95fa7d3b552b35c7e8f3874d74a03a8a69279fd5fca5dc751"}, - {file = "rpds_py-0.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ba6f89cac95c0900d932c9efb7f0fb6ca47f6687feec41abcb1bd5e2bd45535"}, - {file = "rpds_py-0.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a916087371afd9648e1962e67403c53f9c49ca47b9680adbeef79da3a7811b0"}, - {file = "rpds_py-0.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:200a23239781f46149e6a415f1e870c5ef1e712939fe8fa63035cd053ac2638e"}, - {file = "rpds_py-0.20.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:58b1d5dd591973d426cbb2da5e27ba0339209832b2f3315928c9790e13f159e8"}, - {file = "rpds_py-0.20.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6b73c67850ca7cae0f6c56f71e356d7e9fa25958d3e18a64927c2d930859b8e4"}, - {file = "rpds_py-0.20.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d8761c3c891cc51e90bc9926d6d2f59b27beaf86c74622c8979380a29cc23ac3"}, - {file = "rpds_py-0.20.1-cp311-none-win32.whl", hash = "sha256:cd945871335a639275eee904caef90041568ce3b42f402c6959b460d25ae8732"}, - {file = "rpds_py-0.20.1-cp311-none-win_amd64.whl", hash = "sha256:7e21b7031e17c6b0e445f42ccc77f79a97e2687023c5746bfb7a9e45e0921b84"}, - {file = "rpds_py-0.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:36785be22066966a27348444b40389f8444671630063edfb1a2eb04318721e17"}, - {file = "rpds_py-0.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:142c0a5124d9bd0e2976089484af5c74f47bd3298f2ed651ef54ea728d2ea42c"}, - {file = "rpds_py-0.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbddc10776ca7ebf2a299c41a4dde8ea0d8e3547bfd731cb87af2e8f5bf8962d"}, - {file = "rpds_py-0.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:15a842bb369e00295392e7ce192de9dcbf136954614124a667f9f9f17d6a216f"}, - {file = "rpds_py-0.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be5ef2f1fc586a7372bfc355986226484e06d1dc4f9402539872c8bb99e34b01"}, - {file = "rpds_py-0.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbcf360c9e3399b056a238523146ea77eeb2a596ce263b8814c900263e46031a"}, - {file = "rpds_py-0.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecd27a66740ffd621d20b9a2f2b5ee4129a56e27bfb9458a3bcc2e45794c96cb"}, - {file = "rpds_py-0.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0b937b2a1988f184a3e9e577adaa8aede21ec0b38320d6009e02bd026db04fa"}, - {file = "rpds_py-0.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6889469bfdc1eddf489729b471303739bf04555bb151fe8875931f8564309afc"}, - {file = "rpds_py-0.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:19b73643c802f4eaf13d97f7855d0fb527fbc92ab7013c4ad0e13a6ae0ed23bd"}, - {file = "rpds_py-0.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3c6afcf2338e7f374e8edc765c79fbcb4061d02b15dd5f8f314a4af2bdc7feb5"}, - {file = "rpds_py-0.20.1-cp312-none-win32.whl", hash = "sha256:dc73505153798c6f74854aba69cc75953888cf9866465196889c7cdd351e720c"}, - {file = "rpds_py-0.20.1-cp312-none-win_amd64.whl", hash = "sha256:8bbe951244a838a51289ee53a6bae3a07f26d4e179b96fc7ddd3301caf0518eb"}, - {file = "rpds_py-0.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:6ca91093a4a8da4afae7fe6a222c3b53ee4eef433ebfee4d54978a103435159e"}, - {file = "rpds_py-0.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b9c2fe36d1f758b28121bef29ed1dee9b7a2453e997528e7d1ac99b94892527c"}, - {file = "rpds_py-0.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f009c69bc8c53db5dfab72ac760895dc1f2bc1b62ab7408b253c8d1ec52459fc"}, - {file = "rpds_py-0.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6740a3e8d43a32629bb9b009017ea5b9e713b7210ba48ac8d4cb6d99d86c8ee8"}, - {file = "rpds_py-0.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:32b922e13d4c0080d03e7b62991ad7f5007d9cd74e239c4b16bc85ae8b70252d"}, - {file = "rpds_py-0.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe00a9057d100e69b4ae4a094203a708d65b0f345ed546fdef86498bf5390982"}, - {file = "rpds_py-0.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49fe9b04b6fa685bd39237d45fad89ba19e9163a1ccaa16611a812e682913496"}, - {file = "rpds_py-0.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aa7ac11e294304e615b43f8c441fee5d40094275ed7311f3420d805fde9b07b4"}, - {file = "rpds_py-0.20.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aa97af1558a9bef4025f8f5d8c60d712e0a3b13a2fe875511defc6ee77a1ab7"}, - {file = "rpds_py-0.20.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:483b29f6f7ffa6af845107d4efe2e3fa8fb2693de8657bc1849f674296ff6a5a"}, - {file = "rpds_py-0.20.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:37fe0f12aebb6a0e3e17bb4cd356b1286d2d18d2e93b2d39fe647138458b4bcb"}, - {file = "rpds_py-0.20.1-cp313-none-win32.whl", hash = "sha256:a624cc00ef2158e04188df5e3016385b9353638139a06fb77057b3498f794782"}, - {file = "rpds_py-0.20.1-cp313-none-win_amd64.whl", hash = "sha256:b71b8666eeea69d6363248822078c075bac6ed135faa9216aa85f295ff009b1e"}, - {file = "rpds_py-0.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:5b48e790e0355865197ad0aca8cde3d8ede347831e1959e158369eb3493d2191"}, - {file = "rpds_py-0.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3e310838a5801795207c66c73ea903deda321e6146d6f282e85fa7e3e4854804"}, - {file = "rpds_py-0.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2249280b870e6a42c0d972339e9cc22ee98730a99cd7f2f727549af80dd5a963"}, - {file = "rpds_py-0.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e79059d67bea28b53d255c1437b25391653263f0e69cd7dec170d778fdbca95e"}, - {file = "rpds_py-0.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b431c777c9653e569986ecf69ff4a5dba281cded16043d348bf9ba505486f36"}, - {file = "rpds_py-0.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da584ff96ec95e97925174eb8237e32f626e7a1a97888cdd27ee2f1f24dd0ad8"}, - {file = "rpds_py-0.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a0629ec053fc013808a85178524e3cb63a61dbc35b22499870194a63578fb9"}, - {file = "rpds_py-0.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fbf15aff64a163db29a91ed0868af181d6f68ec1a3a7d5afcfe4501252840bad"}, - {file = "rpds_py-0.20.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:07924c1b938798797d60c6308fa8ad3b3f0201802f82e4a2c41bb3fafb44cc28"}, - {file = "rpds_py-0.20.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4a5a844f68776a7715ecb30843b453f07ac89bad393431efbf7accca3ef599c1"}, - {file = "rpds_py-0.20.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:518d2ca43c358929bf08f9079b617f1c2ca6e8848f83c1225c88caeac46e6cbc"}, - {file = "rpds_py-0.20.1-cp38-none-win32.whl", hash = "sha256:3aea7eed3e55119635a74bbeb80b35e776bafccb70d97e8ff838816c124539f1"}, - {file = "rpds_py-0.20.1-cp38-none-win_amd64.whl", hash = "sha256:7dca7081e9a0c3b6490a145593f6fe3173a94197f2cb9891183ef75e9d64c425"}, - {file = "rpds_py-0.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b41b6321805c472f66990c2849e152aff7bc359eb92f781e3f606609eac877ad"}, - {file = "rpds_py-0.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a90c373ea2975519b58dece25853dbcb9779b05cc46b4819cb1917e3b3215b6"}, - {file = "rpds_py-0.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16d4477bcb9fbbd7b5b0e4a5d9b493e42026c0bf1f06f723a9353f5153e75d30"}, - {file = "rpds_py-0.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:84b8382a90539910b53a6307f7c35697bc7e6ffb25d9c1d4e998a13e842a5e83"}, - {file = "rpds_py-0.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4888e117dd41b9d34194d9e31631af70d3d526efc363085e3089ab1a62c32ed1"}, - {file = "rpds_py-0.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5265505b3d61a0f56618c9b941dc54dc334dc6e660f1592d112cd103d914a6db"}, - {file = "rpds_py-0.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e75ba609dba23f2c95b776efb9dd3f0b78a76a151e96f96cc5b6b1b0004de66f"}, - {file = "rpds_py-0.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1791ff70bc975b098fe6ecf04356a10e9e2bd7dc21fa7351c1742fdeb9b4966f"}, - {file = "rpds_py-0.20.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d126b52e4a473d40232ec2052a8b232270ed1f8c9571aaf33f73a14cc298c24f"}, - {file = "rpds_py-0.20.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c14937af98c4cc362a1d4374806204dd51b1e12dded1ae30645c298e5a5c4cb1"}, - {file = "rpds_py-0.20.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3d089d0b88996df627693639d123c8158cff41c0651f646cd8fd292c7da90eaf"}, - {file = "rpds_py-0.20.1-cp39-none-win32.whl", hash = "sha256:653647b8838cf83b2e7e6a0364f49af96deec64d2a6578324db58380cff82aca"}, - {file = "rpds_py-0.20.1-cp39-none-win_amd64.whl", hash = "sha256:fa41a64ac5b08b292906e248549ab48b69c5428f3987b09689ab2441f267d04d"}, - {file = "rpds_py-0.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7a07ced2b22f0cf0b55a6a510078174c31b6d8544f3bc00c2bcee52b3d613f74"}, - {file = "rpds_py-0.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:68cb0a499f2c4a088fd2f521453e22ed3527154136a855c62e148b7883b99f9a"}, - {file = "rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa3060d885657abc549b2a0f8e1b79699290e5d83845141717c6c90c2df38311"}, - {file = "rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:95f3b65d2392e1c5cec27cff08fdc0080270d5a1a4b2ea1d51d5f4a2620ff08d"}, - {file = "rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2cc3712a4b0b76a1d45a9302dd2f53ff339614b1c29603a911318f2357b04dd2"}, - {file = "rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d4eea0761e37485c9b81400437adb11c40e13ef513375bbd6973e34100aeb06"}, - {file = "rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f5179583d7a6cdb981151dd349786cbc318bab54963a192692d945dd3f6435d"}, - {file = "rpds_py-0.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2fbb0ffc754490aff6dabbf28064be47f0f9ca0b9755976f945214965b3ace7e"}, - {file = "rpds_py-0.20.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:a94e52537a0e0a85429eda9e49f272ada715506d3b2431f64b8a3e34eb5f3e75"}, - {file = "rpds_py-0.20.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:92b68b79c0da2a980b1c4197e56ac3dd0c8a149b4603747c4378914a68706979"}, - {file = "rpds_py-0.20.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:93da1d3db08a827eda74356f9f58884adb254e59b6664f64cc04cdff2cc19b0d"}, - {file = "rpds_py-0.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:754bbed1a4ca48479e9d4182a561d001bbf81543876cdded6f695ec3d465846b"}, - {file = "rpds_py-0.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ca449520e7484534a2a44faf629362cae62b660601432d04c482283c47eaebab"}, - {file = "rpds_py-0.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:9c4cb04a16b0f199a8c9bf807269b2f63b7b5b11425e4a6bd44bd6961d28282c"}, - {file = "rpds_py-0.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb63804105143c7e24cee7db89e37cb3f3941f8e80c4379a0b355c52a52b6780"}, - {file = "rpds_py-0.20.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:55cd1fa4ecfa6d9f14fbd97ac24803e6f73e897c738f771a9fe038f2f11ff07c"}, - {file = "rpds_py-0.20.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f8f741b6292c86059ed175d80eefa80997125b7c478fb8769fd9ac8943a16c0"}, - {file = "rpds_py-0.20.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fc212779bf8411667234b3cdd34d53de6c2b8b8b958e1e12cb473a5f367c338"}, - {file = "rpds_py-0.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ad56edabcdb428c2e33bbf24f255fe2b43253b7d13a2cdbf05de955217313e6"}, - {file = "rpds_py-0.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0a3a1e9ee9728b2c1734f65d6a1d376c6f2f6fdcc13bb007a08cc4b1ff576dc5"}, - {file = "rpds_py-0.20.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:e13de156137b7095442b288e72f33503a469aa1980ed856b43c353ac86390519"}, - {file = "rpds_py-0.20.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:07f59760ef99f31422c49038964b31c4dfcfeb5d2384ebfc71058a7c9adae2d2"}, - {file = "rpds_py-0.20.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:59240685e7da61fb78f65a9f07f8108e36a83317c53f7b276b4175dc44151684"}, - {file = "rpds_py-0.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:83cba698cfb3c2c5a7c3c6bac12fe6c6a51aae69513726be6411076185a8b24a"}, - {file = "rpds_py-0.20.1.tar.gz", hash = "sha256:e1791c4aabd117653530dccd24108fa03cc6baf21f58b950d0a73c3b3b29a350"}, + {file = "rpds_py-0.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:68afeec26d42ab3b47e541b272166a0b4400313946871cba3ed3a4fc0cab1cef"}, + {file = "rpds_py-0.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74e5b2f7bb6fa38b1b10546d27acbacf2a022a8b5543efb06cfebc72a59c85be"}, + {file = "rpds_py-0.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9024de74731df54546fab0bfbcdb49fae19159ecaecfc8f37c18d2c7e2c0bd61"}, + {file = "rpds_py-0.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:31d3ebadefcd73b73928ed0b2fd696f7fefda8629229f81929ac9c1854d0cffb"}, + {file = "rpds_py-0.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2e7f8f169d775dd9092a1743768d771f1d1300453ddfe6325ae3ab5332b4657"}, + {file = "rpds_py-0.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d905d16f77eb6ab2e324e09bfa277b4c8e5e6b8a78a3e7ff8f3cdf773b4c013"}, + {file = "rpds_py-0.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50c946f048209e6362e22576baea09193809f87687a95a8db24e5fbdb307b93a"}, + {file = "rpds_py-0.27.1-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:3deab27804d65cd8289eb814c2c0e807c4b9d9916c9225e363cb0cf875eb67c1"}, + {file = "rpds_py-0.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8b61097f7488de4be8244c89915da8ed212832ccf1e7c7753a25a394bf9b1f10"}, + {file = "rpds_py-0.27.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8a3f29aba6e2d7d90528d3c792555a93497fe6538aa65eb675b44505be747808"}, + {file = "rpds_py-0.27.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dd6cd0485b7d347304067153a6dc1d73f7d4fd995a396ef32a24d24b8ac63ac8"}, + {file = "rpds_py-0.27.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6f4461bf931108c9fa226ffb0e257c1b18dc2d44cd72b125bec50ee0ab1248a9"}, + {file = "rpds_py-0.27.1-cp310-cp310-win32.whl", hash = "sha256:ee5422d7fb21f6a00c1901bf6559c49fee13a5159d0288320737bbf6585bd3e4"}, + {file = "rpds_py-0.27.1-cp310-cp310-win_amd64.whl", hash = "sha256:3e039aabf6d5f83c745d5f9a0a381d031e9ed871967c0a5c38d201aca41f3ba1"}, + {file = "rpds_py-0.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:be898f271f851f68b318872ce6ebebbc62f303b654e43bf72683dbdc25b7c881"}, + {file = "rpds_py-0.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:62ac3d4e3e07b58ee0ddecd71d6ce3b1637de2d373501412df395a0ec5f9beb5"}, + {file = "rpds_py-0.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4708c5c0ceb2d034f9991623631d3d23cb16e65c83736ea020cdbe28d57c0a0e"}, + {file = "rpds_py-0.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:abfa1171a9952d2e0002aba2ad3780820b00cc3d9c98c6630f2e93271501f66c"}, + {file = "rpds_py-0.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b507d19f817ebaca79574b16eb2ae412e5c0835542c93fe9983f1e432aca195"}, + {file = "rpds_py-0.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:168b025f8fd8d8d10957405f3fdcef3dc20f5982d398f90851f4abc58c566c52"}, + {file = "rpds_py-0.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb56c6210ef77caa58e16e8c17d35c63fe3f5b60fd9ba9d424470c3400bcf9ed"}, + {file = "rpds_py-0.27.1-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:d252f2d8ca0195faa707f8eb9368955760880b2b42a8ee16d382bf5dd807f89a"}, + {file = "rpds_py-0.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6e5e54da1e74b91dbc7996b56640f79b195d5925c2b78efaa8c5d53e1d88edde"}, + {file = "rpds_py-0.27.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ffce0481cc6e95e5b3f0a47ee17ffbd234399e6d532f394c8dce320c3b089c21"}, + {file = "rpds_py-0.27.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a205fdfe55c90c2cd8e540ca9ceba65cbe6629b443bc05db1f590a3db8189ff9"}, + {file = "rpds_py-0.27.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:689fb5200a749db0415b092972e8eba85847c23885c8543a8b0f5c009b1a5948"}, + {file = "rpds_py-0.27.1-cp311-cp311-win32.whl", hash = "sha256:3182af66048c00a075010bc7f4860f33913528a4b6fc09094a6e7598e462fe39"}, + {file = "rpds_py-0.27.1-cp311-cp311-win_amd64.whl", hash = "sha256:b4938466c6b257b2f5c4ff98acd8128ec36b5059e5c8f8372d79316b1c36bb15"}, + {file = "rpds_py-0.27.1-cp311-cp311-win_arm64.whl", hash = "sha256:2f57af9b4d0793e53266ee4325535a31ba48e2f875da81a9177c9926dfa60746"}, + {file = "rpds_py-0.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ae2775c1973e3c30316892737b91f9283f9908e3cc7625b9331271eaaed7dc90"}, + {file = "rpds_py-0.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2643400120f55c8a96f7c9d858f7be0c88d383cd4653ae2cf0d0c88f668073e5"}, + {file = "rpds_py-0.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16323f674c089b0360674a4abd28d5042947d54ba620f72514d69be4ff64845e"}, + {file = "rpds_py-0.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a1f4814b65eacac94a00fc9a526e3fdafd78e439469644032032d0d63de4881"}, + {file = "rpds_py-0.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ba32c16b064267b22f1850a34051121d423b6f7338a12b9459550eb2096e7ec"}, + {file = "rpds_py-0.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5c20f33fd10485b80f65e800bbe5f6785af510b9f4056c5a3c612ebc83ba6cb"}, + {file = "rpds_py-0.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:466bfe65bd932da36ff279ddd92de56b042f2266d752719beb97b08526268ec5"}, + {file = "rpds_py-0.27.1-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:41e532bbdcb57c92ba3be62c42e9f096431b4cf478da9bc3bc6ce5c38ab7ba7a"}, + {file = "rpds_py-0.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f149826d742b406579466283769a8ea448eed82a789af0ed17b0cd5770433444"}, + {file = "rpds_py-0.27.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:80c60cfb5310677bd67cb1e85a1e8eb52e12529545441b43e6f14d90b878775a"}, + {file = "rpds_py-0.27.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7ee6521b9baf06085f62ba9c7a3e5becffbc32480d2f1b351559c001c38ce4c1"}, + {file = "rpds_py-0.27.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a512c8263249a9d68cac08b05dd59d2b3f2061d99b322813cbcc14c3c7421998"}, + {file = "rpds_py-0.27.1-cp312-cp312-win32.whl", hash = "sha256:819064fa048ba01b6dadc5116f3ac48610435ac9a0058bbde98e569f9e785c39"}, + {file = "rpds_py-0.27.1-cp312-cp312-win_amd64.whl", hash = "sha256:d9199717881f13c32c4046a15f024971a3b78ad4ea029e8da6b86e5aa9cf4594"}, + {file = "rpds_py-0.27.1-cp312-cp312-win_arm64.whl", hash = "sha256:33aa65b97826a0e885ef6e278fbd934e98cdcfed80b63946025f01e2f5b29502"}, + {file = "rpds_py-0.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e4b9fcfbc021633863a37e92571d6f91851fa656f0180246e84cbd8b3f6b329b"}, + {file = "rpds_py-0.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1441811a96eadca93c517d08df75de45e5ffe68aa3089924f963c782c4b898cf"}, + {file = "rpds_py-0.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55266dafa22e672f5a4f65019015f90336ed31c6383bd53f5e7826d21a0e0b83"}, + {file = "rpds_py-0.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78827d7ac08627ea2c8e02c9e5b41180ea5ea1f747e9db0915e3adf36b62dcf"}, + {file = "rpds_py-0.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae92443798a40a92dc5f0b01d8a7c93adde0c4dc965310a29ae7c64d72b9fad2"}, + {file = "rpds_py-0.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c46c9dd2403b66a2a3b9720ec4b74d4ab49d4fabf9f03dfdce2d42af913fe8d0"}, + {file = "rpds_py-0.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2efe4eb1d01b7f5f1939f4ef30ecea6c6b3521eec451fb93191bf84b2a522418"}, + {file = "rpds_py-0.27.1-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:15d3b4d83582d10c601f481eca29c3f138d44c92187d197aff663a269197c02d"}, + {file = "rpds_py-0.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4ed2e16abbc982a169d30d1a420274a709949e2cbdef119fe2ec9d870b42f274"}, + {file = "rpds_py-0.27.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a75f305c9b013289121ec0f1181931975df78738cdf650093e6b86d74aa7d8dd"}, + {file = "rpds_py-0.27.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:67ce7620704745881a3d4b0ada80ab4d99df390838839921f99e63c474f82cf2"}, + {file = "rpds_py-0.27.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9d992ac10eb86d9b6f369647b6a3f412fc0075cfd5d799530e84d335e440a002"}, + {file = "rpds_py-0.27.1-cp313-cp313-win32.whl", hash = "sha256:4f75e4bd8ab8db624e02c8e2fc4063021b58becdbe6df793a8111d9343aec1e3"}, + {file = "rpds_py-0.27.1-cp313-cp313-win_amd64.whl", hash = "sha256:f9025faafc62ed0b75a53e541895ca272815bec18abe2249ff6501c8f2e12b83"}, + {file = "rpds_py-0.27.1-cp313-cp313-win_arm64.whl", hash = "sha256:ed10dc32829e7d222b7d3b93136d25a406ba9788f6a7ebf6809092da1f4d279d"}, + {file = "rpds_py-0.27.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:92022bbbad0d4426e616815b16bc4127f83c9a74940e1ccf3cfe0b387aba0228"}, + {file = "rpds_py-0.27.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:47162fdab9407ec3f160805ac3e154df042e577dd53341745fc7fb3f625e6d92"}, + {file = "rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb89bec23fddc489e5d78b550a7b773557c9ab58b7946154a10a6f7a214a48b2"}, + {file = "rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e48af21883ded2b3e9eb48cb7880ad8598b31ab752ff3be6457001d78f416723"}, + {file = "rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f5b7bd8e219ed50299e58551a410b64daafb5017d54bbe822e003856f06a802"}, + {file = "rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08f1e20bccf73b08d12d804d6e1c22ca5530e71659e6673bce31a6bb71c1e73f"}, + {file = "rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dc5dceeaefcc96dc192e3a80bbe1d6c410c469e97bdd47494a7d930987f18b2"}, + {file = "rpds_py-0.27.1-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:d76f9cc8665acdc0c9177043746775aa7babbf479b5520b78ae4002d889f5c21"}, + {file = "rpds_py-0.27.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:134fae0e36022edad8290a6661edf40c023562964efea0cc0ec7f5d392d2aaef"}, + {file = "rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb11a4f1b2b63337cfd3b4d110af778a59aae51c81d195768e353d8b52f88081"}, + {file = "rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:13e608ac9f50a0ed4faec0e90ece76ae33b34c0e8656e3dceb9a7db994c692cd"}, + {file = "rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dd2135527aa40f061350c3f8f89da2644de26cd73e4de458e79606384f4f68e7"}, + {file = "rpds_py-0.27.1-cp313-cp313t-win32.whl", hash = "sha256:3020724ade63fe320a972e2ffd93b5623227e684315adce194941167fee02688"}, + {file = "rpds_py-0.27.1-cp313-cp313t-win_amd64.whl", hash = "sha256:8ee50c3e41739886606388ba3ab3ee2aae9f35fb23f833091833255a31740797"}, + {file = "rpds_py-0.27.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:acb9aafccaae278f449d9c713b64a9e68662e7799dbd5859e2c6b3c67b56d334"}, + {file = "rpds_py-0.27.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b7fb801aa7f845ddf601c49630deeeccde7ce10065561d92729bfe81bd21fb33"}, + {file = "rpds_py-0.27.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe0dd05afb46597b9a2e11c351e5e4283c741237e7f617ffb3252780cca9336a"}, + {file = "rpds_py-0.27.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b6dfb0e058adb12d8b1d1b25f686e94ffa65d9995a5157afe99743bf7369d62b"}, + {file = "rpds_py-0.27.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed090ccd235f6fa8bb5861684567f0a83e04f52dfc2e5c05f2e4b1309fcf85e7"}, + {file = "rpds_py-0.27.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf876e79763eecf3e7356f157540d6a093cef395b65514f17a356f62af6cc136"}, + {file = "rpds_py-0.27.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12ed005216a51b1d6e2b02a7bd31885fe317e45897de81d86dcce7d74618ffff"}, + {file = "rpds_py-0.27.1-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:ee4308f409a40e50593c7e3bb8cbe0b4d4c66d1674a316324f0c2f5383b486f9"}, + {file = "rpds_py-0.27.1-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0b08d152555acf1f455154d498ca855618c1378ec810646fcd7c76416ac6dc60"}, + {file = "rpds_py-0.27.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:dce51c828941973a5684d458214d3a36fcd28da3e1875d659388f4f9f12cc33e"}, + {file = "rpds_py-0.27.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:c1476d6f29eb81aa4151c9a31219b03f1f798dc43d8af1250a870735516a1212"}, + {file = "rpds_py-0.27.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3ce0cac322b0d69b63c9cdb895ee1b65805ec9ffad37639f291dd79467bee675"}, + {file = "rpds_py-0.27.1-cp314-cp314-win32.whl", hash = "sha256:dfbfac137d2a3d0725758cd141f878bf4329ba25e34979797c89474a89a8a3a3"}, + {file = "rpds_py-0.27.1-cp314-cp314-win_amd64.whl", hash = "sha256:a6e57b0abfe7cc513450fcf529eb486b6e4d3f8aee83e92eb5f1ef848218d456"}, + {file = "rpds_py-0.27.1-cp314-cp314-win_arm64.whl", hash = "sha256:faf8d146f3d476abfee026c4ae3bdd9ca14236ae4e4c310cbd1cf75ba33d24a3"}, + {file = "rpds_py-0.27.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:ba81d2b56b6d4911ce735aad0a1d4495e808b8ee4dc58715998741a26874e7c2"}, + {file = "rpds_py-0.27.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:84f7d509870098de0e864cad0102711c1e24e9b1a50ee713b65928adb22269e4"}, + {file = "rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9e960fc78fecd1100539f14132425e1d5fe44ecb9239f8f27f079962021523e"}, + {file = "rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:62f85b665cedab1a503747617393573995dac4600ff51869d69ad2f39eb5e817"}, + {file = "rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fed467af29776f6556250c9ed85ea5a4dd121ab56a5f8b206e3e7a4c551e48ec"}, + {file = "rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2729615f9d430af0ae6b36cf042cb55c0936408d543fb691e1a9e36648fd35a"}, + {file = "rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b207d881a9aef7ba753d69c123a35d96ca7cb808056998f6b9e8747321f03b8"}, + {file = "rpds_py-0.27.1-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:639fd5efec029f99b79ae47e5d7e00ad8a773da899b6309f6786ecaf22948c48"}, + {file = "rpds_py-0.27.1-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fecc80cb2a90e28af8a9b366edacf33d7a91cbfe4c2c4544ea1246e949cfebeb"}, + {file = "rpds_py-0.27.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42a89282d711711d0a62d6f57d81aa43a1368686c45bc1c46b7f079d55692734"}, + {file = "rpds_py-0.27.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:cf9931f14223de59551ab9d38ed18d92f14f055a5f78c1d8ad6493f735021bbb"}, + {file = "rpds_py-0.27.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f39f58a27cc6e59f432b568ed8429c7e1641324fbe38131de852cd77b2d534b0"}, + {file = "rpds_py-0.27.1-cp314-cp314t-win32.whl", hash = "sha256:d5fa0ee122dc09e23607a28e6d7b150da16c662e66409bbe85230e4c85bb528a"}, + {file = "rpds_py-0.27.1-cp314-cp314t-win_amd64.whl", hash = "sha256:6567d2bb951e21232c2f660c24cf3470bb96de56cdcb3f071a83feeaff8a2772"}, + {file = "rpds_py-0.27.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c918c65ec2e42c2a78d19f18c553d77319119bf43aa9e2edf7fb78d624355527"}, + {file = "rpds_py-0.27.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1fea2b1a922c47c51fd07d656324531adc787e415c8b116530a1d29c0516c62d"}, + {file = "rpds_py-0.27.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbf94c58e8e0cd6b6f38d8de67acae41b3a515c26169366ab58bdca4a6883bb8"}, + {file = "rpds_py-0.27.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c2a8fed130ce946d5c585eddc7c8eeef0051f58ac80a8ee43bd17835c144c2cc"}, + {file = "rpds_py-0.27.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:037a2361db72ee98d829bc2c5b7cc55598ae0a5e0ec1823a56ea99374cfd73c1"}, + {file = "rpds_py-0.27.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5281ed1cc1d49882f9997981c88df1a22e140ab41df19071222f7e5fc4e72125"}, + {file = "rpds_py-0.27.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fd50659a069c15eef8aa3d64bbef0d69fd27bb4a50c9ab4f17f83a16cbf8905"}, + {file = "rpds_py-0.27.1-cp39-cp39-manylinux_2_31_riscv64.whl", hash = "sha256:c4b676c4ae3921649a15d28ed10025548e9b561ded473aa413af749503c6737e"}, + {file = "rpds_py-0.27.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:079bc583a26db831a985c5257797b2b5d3affb0386e7ff886256762f82113b5e"}, + {file = "rpds_py-0.27.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4e44099bd522cba71a2c6b97f68e19f40e7d85399de899d66cdb67b32d7cb786"}, + {file = "rpds_py-0.27.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e202e6d4188e53c6661af813b46c37ca2c45e497fc558bacc1a7630ec2695aec"}, + {file = "rpds_py-0.27.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f41f814b8eaa48768d1bb551591f6ba45f87ac76899453e8ccd41dba1289b04b"}, + {file = "rpds_py-0.27.1-cp39-cp39-win32.whl", hash = "sha256:9e71f5a087ead99563c11fdaceee83ee982fd39cf67601f4fd66cb386336ee52"}, + {file = "rpds_py-0.27.1-cp39-cp39-win_amd64.whl", hash = "sha256:71108900c9c3c8590697244b9519017a400d9ba26a36c48381b3f64743a44aab"}, + {file = "rpds_py-0.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7ba22cb9693df986033b91ae1d7a979bc399237d45fccf875b76f62bb9e52ddf"}, + {file = "rpds_py-0.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5b640501be9288c77738b5492b3fd3abc4ba95c50c2e41273c8a1459f08298d3"}, + {file = "rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb08b65b93e0c6dd70aac7f7890a9c0938d5ec71d5cb32d45cf844fb8ae47636"}, + {file = "rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d7ff07d696a7a38152ebdb8212ca9e5baab56656749f3d6004b34ab726b550b8"}, + {file = "rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fb7c72262deae25366e3b6c0c0ba46007967aea15d1eea746e44ddba8ec58dcc"}, + {file = "rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b002cab05d6339716b03a4a3a2ce26737f6231d7b523f339fa061d53368c9d8"}, + {file = "rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23f6b69d1c26c4704fec01311963a41d7de3ee0570a84ebde4d544e5a1859ffc"}, + {file = "rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:530064db9146b247351f2a0250b8f00b289accea4596a033e94be2389977de71"}, + {file = "rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7b90b0496570bd6b0321724a330d8b545827c4df2034b6ddfc5f5275f55da2ad"}, + {file = "rpds_py-0.27.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:879b0e14a2da6a1102a3fc8af580fc1ead37e6d6692a781bd8c83da37429b5ab"}, + {file = "rpds_py-0.27.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:0d807710df3b5faa66c731afa162ea29717ab3be17bdc15f90f2d9f183da4059"}, + {file = "rpds_py-0.27.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:3adc388fc3afb6540aec081fa59e6e0d3908722771aa1e37ffe22b220a436f0b"}, + {file = "rpds_py-0.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c796c0c1cc68cb08b0284db4229f5af76168172670c74908fdbd4b7d7f515819"}, + {file = "rpds_py-0.27.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cdfe4bb2f9fe7458b7453ad3c33e726d6d1c7c0a72960bcc23800d77384e42df"}, + {file = "rpds_py-0.27.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:8fabb8fd848a5f75a2324e4a84501ee3a5e3c78d8603f83475441866e60b94a3"}, + {file = "rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eda8719d598f2f7f3e0f885cba8646644b55a187762bec091fa14a2b819746a9"}, + {file = "rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c64d07e95606ec402a0a1c511fe003873fa6af630bda59bac77fac8b4318ebc"}, + {file = "rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93a2ed40de81bcff59aabebb626562d48332f3d028ca2036f1d23cbb52750be4"}, + {file = "rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:387ce8c44ae94e0ec50532d9cb0edce17311024c9794eb196b90e1058aadeb66"}, + {file = "rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaf94f812c95b5e60ebaf8bfb1898a7d7cb9c1af5744d4a67fa47796e0465d4e"}, + {file = "rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:4848ca84d6ded9b58e474dfdbad4b8bfb450344c0551ddc8d958bf4b36aa837c"}, + {file = "rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2bde09cbcf2248b73c7c323be49b280180ff39fadcfe04e7b6f54a678d02a7cf"}, + {file = "rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:94c44ee01fd21c9058f124d2d4f0c9dc7634bec93cd4b38eefc385dabe71acbf"}, + {file = "rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:df8b74962e35c9249425d90144e721eed198e6555a0e22a563d29fe4486b51f6"}, + {file = "rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:dc23e6820e3b40847e2f4a7726462ba0cf53089512abe9ee16318c366494c17a"}, + {file = "rpds_py-0.27.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:aa8933159edc50be265ed22b401125c9eebff3171f570258854dbce3ecd55475"}, + {file = "rpds_py-0.27.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a50431bf02583e21bf273c71b89d710e7a710ad5e39c725b14e685610555926f"}, + {file = "rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78af06ddc7fe5cc0e967085a9115accee665fb912c22a3f54bad70cc65b05fe6"}, + {file = "rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:70d0738ef8fee13c003b100c2fbd667ec4f133468109b3472d249231108283a3"}, + {file = "rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2f6fd8a1cea5bbe599b6e78a6e5ee08db434fc8ffea51ff201c8765679698b3"}, + {file = "rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8177002868d1426305bb5de1e138161c2ec9eb2d939be38291d7c431c4712df8"}, + {file = "rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:008b839781d6c9bf3b6a8984d1d8e56f0ec46dc56df61fd669c49b58ae800400"}, + {file = "rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:a55b9132bb1ade6c734ddd2759c8dc132aa63687d259e725221f106b83a0e485"}, + {file = "rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a46fdec0083a26415f11d5f236b79fa1291c32aaa4a17684d82f7017a1f818b1"}, + {file = "rpds_py-0.27.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:8a63b640a7845f2bdd232eb0d0a4a2dd939bcdd6c57e6bb134526487f3160ec5"}, + {file = "rpds_py-0.27.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:7e32721e5d4922deaaf963469d795d5bde6093207c52fec719bd22e5d1bedbc4"}, + {file = "rpds_py-0.27.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:2c426b99a068601b5f4623573df7a7c3d72e87533a2dd2253353a03e7502566c"}, + {file = "rpds_py-0.27.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4fc9b7fe29478824361ead6e14e4f5aed570d477e06088826537e202d25fe859"}, + {file = "rpds_py-0.27.1.tar.gz", hash = "sha256:26a1c73171d10b7acccbded82bf6a586ab8203601e565badc74bbbf8bc5a10f8"}, ] [[package]] name = "rpds-py" -version = "0.28.0" +version = "0.30.0" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.10" groups = ["dev"] markers = "python_version >= \"3.11\"" files = [ - {file = "rpds_py-0.28.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7b6013db815417eeb56b2d9d7324e64fcd4fa289caeee6e7a78b2e11fc9b438a"}, - {file = "rpds_py-0.28.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a4c6b05c685c0c03f80dabaeb73e74218c49deea965ca63f76a752807397207"}, - {file = "rpds_py-0.28.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4794c6c3fbe8f9ac87699b131a1f26e7b4abcf6d828da46a3a52648c7930eba"}, - {file = "rpds_py-0.28.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2e8456b6ee5527112ff2354dd9087b030e3429e43a74f480d4a5ca79d269fd85"}, - {file = "rpds_py-0.28.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:beb880a9ca0a117415f241f66d56025c02037f7c4efc6fe59b5b8454f1eaa50d"}, - {file = "rpds_py-0.28.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6897bebb118c44b38c9cb62a178e09f1593c949391b9a1a6fe777ccab5934ee7"}, - {file = "rpds_py-0.28.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1b553dd06e875249fd43efd727785efb57a53180e0fde321468222eabbeaafa"}, - {file = "rpds_py-0.28.0-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:f0b2044fdddeea5b05df832e50d2a06fe61023acb44d76978e1b060206a8a476"}, - {file = "rpds_py-0.28.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05cf1e74900e8da73fa08cc76c74a03345e5a3e37691d07cfe2092d7d8e27b04"}, - {file = "rpds_py-0.28.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:efd489fec7c311dae25e94fe7eeda4b3d06be71c68f2cf2e8ef990ffcd2cd7e8"}, - {file = "rpds_py-0.28.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ada7754a10faacd4f26067e62de52d6af93b6d9542f0df73c57b9771eb3ba9c4"}, - {file = "rpds_py-0.28.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c2a34fd26588949e1e7977cfcbb17a9a42c948c100cab890c6d8d823f0586457"}, - {file = "rpds_py-0.28.0-cp310-cp310-win32.whl", hash = "sha256:f9174471d6920cbc5e82a7822de8dfd4dcea86eb828b04fc8c6519a77b0ee51e"}, - {file = "rpds_py-0.28.0-cp310-cp310-win_amd64.whl", hash = "sha256:6e32dd207e2c4f8475257a3540ab8a93eff997abfa0a3fdb287cae0d6cd874b8"}, - {file = "rpds_py-0.28.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:03065002fd2e287725d95fbc69688e0c6daf6c6314ba38bdbaa3895418e09296"}, - {file = "rpds_py-0.28.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:28ea02215f262b6d078daec0b45344c89e161eab9526b0d898221d96fdda5f27"}, - {file = "rpds_py-0.28.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25dbade8fbf30bcc551cb352376c0ad64b067e4fc56f90e22ba70c3ce205988c"}, - {file = "rpds_py-0.28.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c03002f54cc855860bfdc3442928ffdca9081e73b5b382ed0b9e8efe6e5e205"}, - {file = "rpds_py-0.28.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b9699fa7990368b22032baf2b2dce1f634388e4ffc03dfefaaac79f4695edc95"}, - {file = "rpds_py-0.28.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9b06fe1a75e05e0713f06ea0c89ecb6452210fd60e2f1b6ddc1067b990e08d9"}, - {file = "rpds_py-0.28.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac9f83e7b326a3f9ec3ef84cda98fb0a74c7159f33e692032233046e7fd15da2"}, - {file = "rpds_py-0.28.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:0d3259ea9ad8743a75a43eb7819324cdab393263c91be86e2d1901ee65c314e0"}, - {file = "rpds_py-0.28.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a7548b345f66f6695943b4ef6afe33ccd3f1b638bd9afd0f730dd255c249c9e"}, - {file = "rpds_py-0.28.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c9a40040aa388b037eb39416710fbcce9443498d2eaab0b9b45ae988b53f5c67"}, - {file = "rpds_py-0.28.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8f60c7ea34e78c199acd0d3cda37a99be2c861dd2b8cf67399784f70c9f8e57d"}, - {file = "rpds_py-0.28.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1571ae4292649100d743b26d5f9c63503bb1fedf538a8f29a98dce2d5ba6b4e6"}, - {file = "rpds_py-0.28.0-cp311-cp311-win32.whl", hash = "sha256:5cfa9af45e7c1140af7321fa0bef25b386ee9faa8928c80dc3a5360971a29e8c"}, - {file = "rpds_py-0.28.0-cp311-cp311-win_amd64.whl", hash = "sha256:dd8d86b5d29d1b74100982424ba53e56033dc47720a6de9ba0259cf81d7cecaa"}, - {file = "rpds_py-0.28.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e27d3a5709cc2b3e013bf93679a849213c79ae0573f9b894b284b55e729e120"}, - {file = "rpds_py-0.28.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6b4f28583a4f247ff60cd7bdda83db8c3f5b05a7a82ff20dd4b078571747708f"}, - {file = "rpds_py-0.28.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d678e91b610c29c4b3d52a2c148b641df2b4676ffe47c59f6388d58b99cdc424"}, - {file = "rpds_py-0.28.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e819e0e37a44a78e1383bf1970076e2ccc4dc8c2bbaa2f9bd1dc987e9afff628"}, - {file = "rpds_py-0.28.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5ee514e0f0523db5d3fb171f397c54875dbbd69760a414dccf9d4d7ad628b5bd"}, - {file = "rpds_py-0.28.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5f3fa06d27fdcee47f07a39e02862da0100cb4982508f5ead53ec533cd5fe55e"}, - {file = "rpds_py-0.28.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:46959ef2e64f9e4a41fc89aa20dbca2b85531f9a72c21099a3360f35d10b0d5a"}, - {file = "rpds_py-0.28.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8455933b4bcd6e83fde3fefc987a023389c4b13f9a58c8d23e4b3f6d13f78c84"}, - {file = "rpds_py-0.28.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:ad50614a02c8c2962feebe6012b52f9802deec4263946cddea37aaf28dd25a66"}, - {file = "rpds_py-0.28.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e5deca01b271492553fdb6c7fd974659dce736a15bae5dad7ab8b93555bceb28"}, - {file = "rpds_py-0.28.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:735f8495a13159ce6a0d533f01e8674cec0c57038c920495f87dcb20b3ddb48a"}, - {file = "rpds_py-0.28.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:961ca621ff10d198bbe6ba4957decca61aa2a0c56695384c1d6b79bf61436df5"}, - {file = "rpds_py-0.28.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2374e16cc9131022e7d9a8f8d65d261d9ba55048c78f3b6e017971a4f5e6353c"}, - {file = "rpds_py-0.28.0-cp312-cp312-win32.whl", hash = "sha256:d15431e334fba488b081d47f30f091e5d03c18527c325386091f31718952fe08"}, - {file = "rpds_py-0.28.0-cp312-cp312-win_amd64.whl", hash = "sha256:a410542d61fc54710f750d3764380b53bf09e8c4edbf2f9141a82aa774a04f7c"}, - {file = "rpds_py-0.28.0-cp312-cp312-win_arm64.whl", hash = "sha256:1f0cfd1c69e2d14f8c892b893997fa9a60d890a0c8a603e88dca4955f26d1edd"}, - {file = "rpds_py-0.28.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e9e184408a0297086f880556b6168fa927d677716f83d3472ea333b42171ee3b"}, - {file = "rpds_py-0.28.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:edd267266a9b0448f33dc465a97cfc5d467594b600fe28e7fa2f36450e03053a"}, - {file = "rpds_py-0.28.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85beb8b3f45e4e32f6802fb6cd6b17f615ef6c6a52f265371fb916fae02814aa"}, - {file = "rpds_py-0.28.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d2412be8d00a1b895f8ad827cc2116455196e20ed994bb704bf138fe91a42724"}, - {file = "rpds_py-0.28.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cf128350d384b777da0e68796afdcebc2e9f63f0e9f242217754e647f6d32491"}, - {file = "rpds_py-0.28.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a2036d09b363aa36695d1cc1a97b36865597f4478470b0697b5ee9403f4fe399"}, - {file = "rpds_py-0.28.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8e1e9be4fa6305a16be628959188e4fd5cd6f1b0e724d63c6d8b2a8adf74ea6"}, - {file = "rpds_py-0.28.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0a403460c9dd91a7f23fc3188de6d8977f1d9603a351d5db6cf20aaea95b538d"}, - {file = "rpds_py-0.28.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d7366b6553cdc805abcc512b849a519167db8f5e5c3472010cd1228b224265cb"}, - {file = "rpds_py-0.28.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5b43c6a3726efd50f18d8120ec0551241c38785b68952d240c45ea553912ac41"}, - {file = "rpds_py-0.28.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0cb7203c7bc69d7c1585ebb33a2e6074492d2fc21ad28a7b9d40457ac2a51ab7"}, - {file = "rpds_py-0.28.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7a52a5169c664dfb495882adc75c304ae1d50df552fbd68e100fdc719dee4ff9"}, - {file = "rpds_py-0.28.0-cp313-cp313-win32.whl", hash = "sha256:2e42456917b6687215b3e606ab46aa6bca040c77af7df9a08a6dcfe8a4d10ca5"}, - {file = "rpds_py-0.28.0-cp313-cp313-win_amd64.whl", hash = "sha256:e0a0311caedc8069d68fc2bf4c9019b58a2d5ce3cd7cb656c845f1615b577e1e"}, - {file = "rpds_py-0.28.0-cp313-cp313-win_arm64.whl", hash = "sha256:04c1b207ab8b581108801528d59ad80aa83bb170b35b0ddffb29c20e411acdc1"}, - {file = "rpds_py-0.28.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:f296ea3054e11fc58ad42e850e8b75c62d9a93a9f981ad04b2e5ae7d2186ff9c"}, - {file = "rpds_py-0.28.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5a7306c19b19005ad98468fcefeb7100b19c79fc23a5f24a12e06d91181193fa"}, - {file = "rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5d9b86aa501fed9862a443c5c3116f6ead8bc9296185f369277c42542bd646b"}, - {file = "rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e5bbc701eff140ba0e872691d573b3d5d30059ea26e5785acba9132d10c8c31d"}, - {file = "rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a5690671cd672a45aa8616d7374fdf334a1b9c04a0cac3c854b1136e92374fe"}, - {file = "rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9f1d92ecea4fa12f978a367c32a5375a1982834649cdb96539dcdc12e609ab1a"}, - {file = "rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d252db6b1a78d0a3928b6190156042d54c93660ce4d98290d7b16b5296fb7cc"}, - {file = "rpds_py-0.28.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:d61b355c3275acb825f8777d6c4505f42b5007e357af500939d4a35b19177259"}, - {file = "rpds_py-0.28.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:acbe5e8b1026c0c580d0321c8aae4b0a1e1676861d48d6e8c6586625055b606a"}, - {file = "rpds_py-0.28.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8aa23b6f0fc59b85b4c7d89ba2965af274346f738e8d9fc2455763602e62fd5f"}, - {file = "rpds_py-0.28.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7b14b0c680286958817c22d76fcbca4800ddacef6f678f3a7c79a1fe7067fe37"}, - {file = "rpds_py-0.28.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bcf1d210dfee61a6c86551d67ee1031899c0fdbae88b2d44a569995d43797712"}, - {file = "rpds_py-0.28.0-cp313-cp313t-win32.whl", hash = "sha256:3aa4dc0fdab4a7029ac63959a3ccf4ed605fee048ba67ce89ca3168da34a1342"}, - {file = "rpds_py-0.28.0-cp313-cp313t-win_amd64.whl", hash = "sha256:7b7d9d83c942855e4fdcfa75d4f96f6b9e272d42fffcb72cd4bb2577db2e2907"}, - {file = "rpds_py-0.28.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:dcdcb890b3ada98a03f9f2bb108489cdc7580176cb73b4f2d789e9a1dac1d472"}, - {file = "rpds_py-0.28.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f274f56a926ba2dc02976ca5b11c32855cbd5925534e57cfe1fda64e04d1add2"}, - {file = "rpds_py-0.28.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fe0438ac4a29a520ea94c8c7f1754cdd8feb1bc490dfda1bfd990072363d527"}, - {file = "rpds_py-0.28.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a358a32dd3ae50e933347889b6af9a1bdf207ba5d1a3f34e1a38cd3540e6733"}, - {file = "rpds_py-0.28.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e80848a71c78aa328fefaba9c244d588a342c8e03bda518447b624ea64d1ff56"}, - {file = "rpds_py-0.28.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f586db2e209d54fe177e58e0bc4946bea5fb0102f150b1b2f13de03e1f0976f8"}, - {file = "rpds_py-0.28.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ae8ee156d6b586e4292491e885d41483136ab994e719a13458055bec14cf370"}, - {file = "rpds_py-0.28.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:a805e9b3973f7e27f7cab63a6b4f61d90f2e5557cff73b6e97cd5b8540276d3d"}, - {file = "rpds_py-0.28.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5d3fd16b6dc89c73a4da0b4ac8b12a7ecc75b2864b95c9e5afed8003cb50a728"}, - {file = "rpds_py-0.28.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:6796079e5d24fdaba6d49bda28e2c47347e89834678f2bc2c1b4fc1489c0fb01"}, - {file = "rpds_py-0.28.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:76500820c2af232435cbe215e3324c75b950a027134e044423f59f5b9a1ba515"}, - {file = "rpds_py-0.28.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bbdc5640900a7dbf9dd707fe6388972f5bbd883633eb68b76591044cfe346f7e"}, - {file = "rpds_py-0.28.0-cp314-cp314-win32.whl", hash = "sha256:adc8aa88486857d2b35d75f0640b949759f79dc105f50aa2c27816b2e0dd749f"}, - {file = "rpds_py-0.28.0-cp314-cp314-win_amd64.whl", hash = "sha256:66e6fa8e075b58946e76a78e69e1a124a21d9a48a5b4766d15ba5b06869d1fa1"}, - {file = "rpds_py-0.28.0-cp314-cp314-win_arm64.whl", hash = "sha256:a6fe887c2c5c59413353b7c0caff25d0e566623501ccfff88957fa438a69377d"}, - {file = "rpds_py-0.28.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7a69df082db13c7070f7b8b1f155fa9e687f1d6aefb7b0e3f7231653b79a067b"}, - {file = "rpds_py-0.28.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b1cde22f2c30ebb049a9e74c5374994157b9b70a16147d332f89c99c5960737a"}, - {file = "rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5338742f6ba7a51012ea470bd4dc600a8c713c0c72adaa0977a1b1f4327d6592"}, - {file = "rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e1460ebde1bcf6d496d80b191d854adedcc619f84ff17dc1c6d550f58c9efbba"}, - {file = "rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e3eb248f2feba84c692579257a043a7699e28a77d86c77b032c1d9fbb3f0219c"}, - {file = "rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3bbba5def70b16cd1c1d7255666aad3b290fbf8d0fe7f9f91abafb73611a91"}, - {file = "rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3114f4db69ac5a1f32e7e4d1cbbe7c8f9cf8217f78e6e002cedf2d54c2a548ed"}, - {file = "rpds_py-0.28.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:4b0cb8a906b1a0196b863d460c0222fb8ad0f34041568da5620f9799b83ccf0b"}, - {file = "rpds_py-0.28.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf681ac76a60b667106141e11a92a3330890257e6f559ca995fbb5265160b56e"}, - {file = "rpds_py-0.28.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1e8ee6413cfc677ce8898d9cde18cc3a60fc2ba756b0dec5b71eb6eb21c49fa1"}, - {file = "rpds_py-0.28.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:b3072b16904d0b5572a15eb9d31c1954e0d3227a585fc1351aa9878729099d6c"}, - {file = "rpds_py-0.28.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b670c30fd87a6aec281c3c9896d3bae4b205fd75d79d06dc87c2503717e46092"}, - {file = "rpds_py-0.28.0-cp314-cp314t-win32.whl", hash = "sha256:8014045a15b4d2b3476f0a287fcc93d4f823472d7d1308d47884ecac9e612be3"}, - {file = "rpds_py-0.28.0-cp314-cp314t-win_amd64.whl", hash = "sha256:7a4e59c90d9c27c561eb3160323634a9ff50b04e4f7820600a2beb0ac90db578"}, - {file = "rpds_py-0.28.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f5e7101145427087e493b9c9b959da68d357c28c562792300dd21a095118ed16"}, - {file = "rpds_py-0.28.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:31eb671150b9c62409a888850aaa8e6533635704fe2b78335f9aaf7ff81eec4d"}, - {file = "rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48b55c1f64482f7d8bd39942f376bfdf2f6aec637ee8c805b5041e14eeb771db"}, - {file = "rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24743a7b372e9a76171f6b69c01aedf927e8ac3e16c474d9fe20d552a8cb45c7"}, - {file = "rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:389c29045ee8bbb1627ea190b4976a310a295559eaf9f1464a1a6f2bf84dde78"}, - {file = "rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23690b5827e643150cf7b49569679ec13fe9a610a15949ed48b85eb7f98f34ec"}, - {file = "rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f0c9266c26580e7243ad0d72fc3e01d6b33866cfab5084a6da7576bcf1c4f72"}, - {file = "rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:4c6c4db5d73d179746951486df97fd25e92396be07fc29ee8ff9a8f5afbdfb27"}, - {file = "rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a3b695a8fa799dd2cfdb4804b37096c5f6dba1ac7f48a7fbf6d0485bcd060316"}, - {file = "rpds_py-0.28.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:6aa1bfce3f83baf00d9c5fcdbba93a3ab79958b4c7d7d1f55e7fe68c20e63912"}, - {file = "rpds_py-0.28.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:7b0f9dceb221792b3ee6acb5438eb1f02b0cb2c247796a72b016dcc92c6de829"}, - {file = "rpds_py-0.28.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5d0145edba8abd3db0ab22b5300c99dc152f5c9021fab861be0f0544dc3cbc5f"}, - {file = "rpds_py-0.28.0.tar.gz", hash = "sha256:abd4df20485a0983e2ca334a216249b6186d6e3c1627e106651943dbdb791aea"}, + {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]] @@ -4317,14 +4581,14 @@ test = ["Cython", "array-api-strict (>=2.3.1)", "asv", "gmpy2", "hypothesis (>=6 [[package]] name = "send2trash" -version = "1.8.3" +version = "2.0.0" description = "Send file to trash natively under Mac OS X, Windows and Linux" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*" groups = ["dev"] files = [ - {file = "Send2Trash-1.8.3-py3-none-any.whl", hash = "sha256:0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9"}, - {file = "Send2Trash-1.8.3.tar.gz", hash = "sha256:b18e7a3966d99871aefeb00cfbcfdced55ce4871194810fc71f4aa484b953abf"}, + {file = "send2trash-2.0.0-py3-none-any.whl", hash = "sha256:e70d5ce41dbb890882cc78bc25d137478330b39a391e756fadf82e34da4d85b8"}, + {file = "send2trash-2.0.0.tar.gz", hash = "sha256:1761421da3f9930bfe51ed7c45343948573383ad4c27e3acebc91be324e7770d"}, ] [package.extras] @@ -4500,28 +4764,16 @@ files = [ {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -groups = ["dev"] -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - [[package]] name = "soupsieve" -version = "2.8" +version = "2.8.1" description = "A modern CSS selector implementation for Beautiful Soup." optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c"}, - {file = "soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f"}, + {file = "soupsieve-2.8.1-py3-none-any.whl", hash = "sha256:a11fe2a6f3d76ab3cf2de04eb339c1be5b506a8a47f2ceb6d139803177f85434"}, + {file = "soupsieve-2.8.1.tar.gz", hash = "sha256:4cf733bc50fa805f5df4b8ef4740fc0e0fa6218cf3006269afd3f9d6d80fd350"}, ] [[package]] @@ -4566,26 +4818,6 @@ docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] test = ["pre-commit", "pytest (>=7.0)", "pytest-timeout"] typing = ["mypy (>=1.6,<2.0)", "traitlets (>=5.11.1)"] -[[package]] -name = "tinycss2" -version = "1.2.1" -description = "A tiny CSS parser" -optional = false -python-versions = ">=3.7" -groups = ["dev"] -markers = "python_version < \"3.11\"" -files = [ - {file = "tinycss2-1.2.1-py3-none-any.whl", hash = "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847"}, - {file = "tinycss2-1.2.1.tar.gz", hash = "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627"}, -] - -[package.dependencies] -webencodings = ">=0.4" - -[package.extras] -doc = ["sphinx", "sphinx_rtd_theme"] -test = ["flake8", "isort", "pytest"] - [[package]] name = "tinycss2" version = "1.4.0" @@ -4593,7 +4825,6 @@ description = "A tiny CSS parser" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "python_version >= \"3.11\"" files = [ {file = "tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289"}, {file = "tinycss2-1.4.0.tar.gz", hash = "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7"}, @@ -4673,24 +4904,24 @@ files = [ [[package]] name = "tornado" -version = "6.5.2" +version = "6.5.4" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "tornado-6.5.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2436822940d37cde62771cff8774f4f00b3c8024fe482e16ca8387b8a2724db6"}, - {file = "tornado-6.5.2-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:583a52c7aa94ee046854ba81d9ebb6c81ec0fd30386d96f7640c96dad45a03ef"}, - {file = "tornado-6.5.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0fe179f28d597deab2842b86ed4060deec7388f1fd9c1b4a41adf8af058907e"}, - {file = "tornado-6.5.2-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b186e85d1e3536d69583d2298423744740986018e393d0321df7340e71898882"}, - {file = "tornado-6.5.2-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e792706668c87709709c18b353da1f7662317b563ff69f00bab83595940c7108"}, - {file = "tornado-6.5.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:06ceb1300fd70cb20e43b1ad8aaee0266e69e7ced38fa910ad2e03285009ce7c"}, - {file = "tornado-6.5.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:74db443e0f5251be86cbf37929f84d8c20c27a355dd452a5cfa2aada0d001ec4"}, - {file = "tornado-6.5.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b5e735ab2889d7ed33b32a459cac490eda71a1ba6857b0118de476ab6c366c04"}, - {file = "tornado-6.5.2-cp39-abi3-win32.whl", hash = "sha256:c6f29e94d9b37a95013bb669616352ddb82e3bfe8326fccee50583caebc8a5f0"}, - {file = "tornado-6.5.2-cp39-abi3-win_amd64.whl", hash = "sha256:e56a5af51cc30dd2cae649429af65ca2f6571da29504a07995175df14c18f35f"}, - {file = "tornado-6.5.2-cp39-abi3-win_arm64.whl", hash = "sha256:d6c33dc3672e3a1f3618eb63b7ef4683a7688e7b9e6e8f0d9aa5726360a004af"}, - {file = "tornado-6.5.2.tar.gz", hash = "sha256:ab53c8f9a0fa351e2c0741284e06c7a45da86afb544133201c5cc8578eb076a0"}, + {file = "tornado-6.5.4-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d6241c1a16b1c9e4cc28148b1cda97dd1c6cb4fb7068ac1bedc610768dff0ba9"}, + {file = "tornado-6.5.4-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2d50f63dda1d2cac3ae1fa23d254e16b5e38153758470e9956cbc3d813d40843"}, + {file = "tornado-6.5.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1cf66105dc6acb5af613c054955b8137e34a03698aa53272dbda4afe252be17"}, + {file = "tornado-6.5.4-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50ff0a58b0dc97939d29da29cd624da010e7f804746621c78d14b80238669335"}, + {file = "tornado-6.5.4-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5fb5e04efa54cf0baabdd10061eb4148e0be137166146fff835745f59ab9f7f"}, + {file = "tornado-6.5.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9c86b1643b33a4cd415f8d0fe53045f913bf07b4a3ef646b735a6a86047dda84"}, + {file = "tornado-6.5.4-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:6eb82872335a53dd063a4f10917b3efd28270b56a33db69009606a0312660a6f"}, + {file = "tornado-6.5.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6076d5dda368c9328ff41ab5d9dd3608e695e8225d1cd0fd1e006f05da3635a8"}, + {file = "tornado-6.5.4-cp39-abi3-win32.whl", hash = "sha256:1768110f2411d5cd281bac0a090f707223ce77fd110424361092859e089b38d1"}, + {file = "tornado-6.5.4-cp39-abi3-win_amd64.whl", hash = "sha256:fa07d31e0cd85c60713f2b995da613588aa03e1303d75705dca6af8babc18ddc"}, + {file = "tornado-6.5.4-cp39-abi3-win_arm64.whl", hash = "sha256:053e6e16701eb6cbe641f308f4c1a9541f91b6261991160391bfc342e8a551a1"}, + {file = "tornado-6.5.4.tar.gz", hash = "sha256:a22fa9047405d03260b483980635f0b041989d8bcc9a313f8fe18b411d84b1d7"}, ] [[package]] @@ -4745,14 +4976,14 @@ files = [ [[package]] name = "tzdata" -version = "2025.2" +version = "2025.3" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" groups = ["main", "dev"] files = [ - {file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"}, - {file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"}, + {file = "tzdata-2025.3-py2.py3-none-any.whl", hash = "sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1"}, + {file = "tzdata-2025.3.tar.gz", hash = "sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7"}, ] [[package]] @@ -4800,21 +5031,21 @@ dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake [[package]] name = "urllib3" -version = "2.5.0" +version = "2.6.2" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, - {file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}, + {file = "urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd"}, + {file = "urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797"}, ] [package.extras] -brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] +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 = ["zstandard (>=0.18.0)"] +zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""] [[package]] name = "wcwidth" @@ -4835,11 +5066,25 @@ description = "A library for working with the color formats defined by HTML and optional = false python-versions = ">=3.9" groups = ["dev"] +markers = "python_version < \"3.11\"" files = [ {file = "webcolors-24.11.1-py3-none-any.whl", hash = "sha256:515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9"}, {file = "webcolors-24.11.1.tar.gz", hash = "sha256:ecb3d768f32202af770477b8b65f318fa4f566c22948673a977b00d589dd80f6"}, ] +[[package]] +name = "webcolors" +version = "25.10.0" +description = "A library for working with the color formats defined by HTML and CSS." +optional = false +python-versions = ">=3.10" +groups = ["dev"] +markers = "python_version >= \"3.11\"" +files = [ + {file = "webcolors-25.10.0-py3-none-any.whl", hash = "sha256:032c727334856fc0b968f63daa252a1ac93d33db2f5267756623c210e57a4f1d"}, + {file = "webcolors-25.10.0.tar.gz", hash = "sha256:62abae86504f66d0f6364c2a8520de4a0c47b80c03fc3a5f1815fedbef7c19bf"}, +] + [[package]] name = "webencodings" version = "0.5.1" @@ -4871,27 +5116,27 @@ test = ["pytest", "websockets"] [[package]] name = "widgetsnbextension" -version = "4.0.14" +version = "4.0.15" description = "Jupyter interactive widgets for Jupyter Notebook" optional = false python-versions = ">=3.7" groups = ["dev"] files = [ - {file = "widgetsnbextension-4.0.14-py3-none-any.whl", hash = "sha256:4875a9eaf72fbf5079dc372a51a9f268fc38d46f767cbf85c43a36da5cb9b575"}, - {file = "widgetsnbextension-4.0.14.tar.gz", hash = "sha256:a3629b04e3edb893212df862038c7232f62973373869db5084aed739b437b5af"}, + {file = "widgetsnbextension-4.0.15-py3-none-any.whl", hash = "sha256:8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366"}, + {file = "widgetsnbextension-4.0.15.tar.gz", hash = "sha256:de8610639996f1567952d763a5a41af8af37f2575a41f9852a38f947eb82a3b9"}, ] [[package]] name = "zipp" -version = "3.20.2" +version = "3.23.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["main", "dev", "examples"] markers = "python_version == \"3.9\"" files = [ - {file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"}, - {file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"}, + {file = "zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e"}, + {file = "zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166"}, ] [package.extras] @@ -4899,10 +5144,10 @@ check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \" cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] enabler = ["pytest-enabler (>=2.2)"] -test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more_itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = "^3.9" -content-hash = "4a2f0b1c5894aa64fd619bb5d21363a7895b6ed5f38683efd03c91db167555f4" +content-hash = "276682e947433f51c108591f32d55ee08df61859dce7806b1bfc6bd0e7a35519" diff --git a/pyproject.toml b/pyproject.toml index 6c722a2..64e6cc7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ numpy = ">=1.16.5" scipy = ">=1.6" unified-momentum-model = {git = "https://github.com/Howland-Lab/Unified-Momentum-Model.git"} pyyaml = "^6.0.1" -floris = "^4.5.1" +floris = {git = "https://github.com/misi9170/floris.git", branch = "feature/user-def-op-mod"} [tool.poetry.group.dev.dependencies] black = { extras = ["jupyter"], version = "^23.9.1" } From a6f936d955e6a4a0d499052fad7c1511e431f609 Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Wed, 7 Jan 2026 17:14:26 -0500 Subject: [PATCH 04/19] floris interface tests finished --- MITRotor/FlorisInterface/FlorisInterface.py | 72 +++--- examples/example_05_floris_integration.ipynb | 253 ------------------- examples/example_05_floris_integration.py | 9 +- tests/test_floris_interface.py | 118 +++++++++ 4 files changed, 152 insertions(+), 300 deletions(-) delete mode 100644 examples/example_05_floris_integration.ipynb create mode 100644 tests/test_floris_interface.py diff --git a/MITRotor/FlorisInterface/FlorisInterface.py b/MITRotor/FlorisInterface/FlorisInterface.py index d4285fa..9d97191 100644 --- a/MITRotor/FlorisInterface/FlorisInterface.py +++ b/MITRotor/FlorisInterface/FlorisInterface.py @@ -21,6 +21,14 @@ def default_bem_factory(): geometry=BEMGeometry(Nr=10, Ntheta=20), ) +def default_pitch_csv(): + module_dir = os.path.dirname(__file__) + return os.path.join(module_dir, "pitch_15mw.csv") + +def default_tsr_csv(): + module_dir = os.path.dirname(__file__) + return os.path.join(module_dir, "tsr_15mw.csv") + def csv_to_interp(csv_file): # read in csv data = np.loadtxt(csv_file, delimiter=",", skiprows=1) @@ -32,7 +40,7 @@ def csv_to_interp(csv_file): x = x[idx] y = y[idx] # return interpolator for y - return interp1d(x, y, kind="linear", fill_value=0.0001, bounds_error=False) + return interp1d(x, y, kind="linear", fill_value="extrapolate", bounds_error=False) @define class MITRotorTurbine(BaseOperationModel): @@ -41,20 +49,20 @@ class MITRotorTurbine(BaseOperationModel): """ # user can define a BEM model if they want a different rotor, momentum model, or geometry bem_model = field(init = True, factory = default_bem_factory, type = BEM) + + # user can define csv paths for pitch and tsr values + pitch_csv = field(init = True, factory = default_pitch_csv, type = str) + tsr_csv = field(init = True, factory = default_tsr_csv, type = str) + + # create interp objects based on pitch and tsr csvs + _pitch_interp = field(init=False, default=None, type = interp1d, repr = False) + _tsr_interp = field(init=False, default=None, type = interp1d, repr = False) + # save most recent solution by unique floris arguments _last_key = field(init=False, default=None, type = bytes) _a = field(init=False, default=None, type = NDArrayFloat) _Ct = field(init=False, default=None, type = NDArrayFloat) _power = field(init=False, default=None, type = NDArrayFloat) - # user can define csv paths for pitch and tsr values - module_dir = os.path.dirname(__file__) - default_pitch_csv = os.path.join(module_dir, "pitch_15mw.csv") - default_tsr_csv = os.path.join(module_dir, "tsr_15mw.csv") - pitch_csv = field(init = True, default = default_pitch_csv, type = str) - tsr_csv = field(init = True, default= default_tsr_csv, type = str) - # create interp objects based on pitch and tsr csvs - _pitch_interp = field(init=False, default=None, type = interp1d, repr = False) - _tsr_interp = field(init=False, default=None, type = interp1d, repr = False) def __attrs_post_init__(self): self._pitch_interp = csv_to_interp(self.pitch_csv) @@ -65,20 +73,20 @@ def _get_state_key(self, velocities: np.ndarray, yaw_angles: np.ndarray, tilt_an return velocities.tobytes(), yaw_angles.tobytes(), tilt_angles.tobytes() def _update_solution(self, - power_thrust_table: dict, velocities: NDArrayFloat, air_density: float, yaw_angles: NDArrayFloat, tilt_angles: NDArrayFloat, average_method: str = "cubic-mean", cubature_weights: NDArrayFloat | None = None, - **kwargs, + **_, ): - n_findex, n_turbines = yaw_angles.shape # create cache key for current inputs key = self._get_state_key(velocities, yaw_angles, tilt_angles) # TODO: add more inputs # update solution if conditions are different if key != self._last_key: + n_findex, n_turbines = yaw_angles.shape + # save new key and clear fields self._last_key = key self._a = np.empty((n_findex, n_turbines), dtype=floris_float_type) @@ -91,39 +99,23 @@ def _update_solution(self, method=average_method, cubature_weights=cubature_weights, ) - # update effective velocities for air density - rotor_effective_velocities = rotor_velocity_air_density_correction( - velocities=rotor_average_velocities, - air_density=air_density, - ref_air_density=power_thrust_table["ref_air_density"] - ) + # calculate rotor area + rotor_area = np.pi * self.bem_model.rotor.R**2 # loop over flow conditions for findex in range(n_findex): for tindex in range(n_turbines): - vel = rotor_effective_velocities[findex, tindex] + # get setpoints + vel = rotor_average_velocities[findex, tindex] yaw, tilt = np.deg2rad(yaw_angles[findex, tindex]), np.deg2rad(tilt_angles[findex, tindex]) - pitch_val = np.deg2rad(self._pitch_interp(vel)) - tsr_val = self._tsr_interp(vel) - bem_sol = self.bem_model(pitch_val, tsr_val, yaw = yaw, tilt = tilt) + pitch = np.deg2rad(self._pitch_interp(vel)) + tsr = self._tsr_interp(vel) + # solve BEM + bem_sol = self.bem_model(pitch, tsr, yaw = yaw, tilt = tilt) + # get induction and thrust coeff self._a[findex, tindex] = bem_sol.a() self._Ct[findex, tindex] = bem_sol.Ct() - # calculate power - rotor_area = np.pi * self.bem_model.rotor.R**2 - rotor_uinfty = vel * np.cos(calc_eff_yaw(yaw, tilt)) - - # Construct power interpolant - power_interpolator = interp1d( - power_thrust_table["wind_speed"], - power_thrust_table["power"], - fill_value=0.0, - bounds_error=False, - ) - - # Compute power - power = power_interpolator(rotor_uinfty) * 1e3 # --> I am not sure the rotor_uinfty is the right value... - self._power[findex, tindex] = power # it seems like using Cp (below) should be correct... plot power interpolator... - # self._power[findex, tindex] = 0.5 * bem_sol.Cp() * air_density * rotor_area * (rotor_uinfty)**3 - + # compute power + self._power[findex, tindex] = 0.5 * bem_sol.Cp() * air_density * rotor_area * (vel)**3 return def power(self, **kwargs) -> NDArrayFloat: diff --git a/examples/example_05_floris_integration.ipynb b/examples/example_05_floris_integration.ipynb deleted file mode 100644 index 9552036..0000000 --- a/examples/example_05_floris_integration.ipynb +++ /dev/null @@ -1,253 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 7, - "id": "eb249327", - "metadata": {}, - "outputs": [], - "source": [ - "from MITRotor.FlorisInterface.FlorisInterface import csv_to_interp, MITRotorTurbine\n", - "from floris import FlorisModel, TimeSeries\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "9cc53ad8", - "metadata": {}, - "outputs": [], - "source": [ - "def check_interp(tsr_csv, pitch_csv):\n", - " tsr_interp = csv_to_interp(tsr_csv)\n", - " pitch_interp = csv_to_interp(pitch_csv)\n", - " print(type(pitch_interp))\n", - " # interp values\n", - " x_interp_vals = np.linspace(0, 25, num=100)\n", - " tsr_interp_vals = tsr_interp(x_interp_vals)\n", - " pitch_interp_vals = pitch_interp(x_interp_vals)\n", - " # actual values\n", - " tsr_data = np.loadtxt(tsr_csv, delimiter=\",\", skiprows=1)\n", - " pitch_data = np.loadtxt(pitch_csv, delimiter=\",\", skiprows=1)\n", - " # plot\n", - " plt.plot(x_interp_vals, tsr_interp_vals, label = \"TSR Interpolation\")\n", - " plt.plot(x_interp_vals, pitch_interp_vals, label = \"Pitch Interpolation\")\n", - " plt.scatter(tsr_data[:, 0], tsr_data[:, 1], label = \"TSR Data\")\n", - " plt.scatter(pitch_data[:, 0], pitch_data[:, 1], label = \"Pitch Data\")\n", - " plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "08c83a7f", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tsr_15mw_csv = \"/Users/sky/src/HowlandLab/MITRotor/MITRotor/FlorisInterface/tsr_15mw.csv\"\n", - "pitch_15mw_csv = \"/Users/sky/src/HowlandLab/MITRotor/MITRotor/FlorisInterface/pitch_15mw.csv\"\n", - "check_interp(tsr_15mw_csv, pitch_15mw_csv)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "51835dd1", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tsr_15mw_csv = \"/Users/sky/src/HowlandLab/MITRotor/MITRotor/FlorisInterface/tsr_5mw.csv\"\n", - "pitch_15mw_csv = \"/Users/sky/src/HowlandLab/MITRotor/MITRotor/FlorisInterface/pitch_5mw.csv\"\n", - "check_interp(tsr_15mw_csv, pitch_15mw_csv)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "2a93558a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Powers [W]:\n", - " [[1753954.45917917 354990.76412771]\n", - " [3417797.00509157 737171.66537995]\n", - " [5000000. 4927707.14320011]] \n", - "\n", - "Thrust coefficients [-]:\n", - " [[0.78715145 0.9353766 ]\n", - " [0.78387889 0.86092059]\n", - " [0.55092883 0.74517368]] \n", - "\n", - "Axial induction factors [-]:\n", - " [[0.26932244 0.37289433]\n", - " [0.26755586 0.31353324]\n", - " [0.16493614 0.24759837]] \n", - "\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/sky/Library/Caches/pypoetry/virtualenvs/mitrotor-l4Gn_-ln-py3.12/lib/python3.12/site-packages/floris/core/flow_field.py:172: UserWarning: 'where' used without 'out', expect unitialized memory in output. If this is intentional, use out=None.\n", - " * np.power(\n" - ] - } - ], - "source": [ - "from floris.core.turbine.unified_momentum_model import UnifiedMomentumModelTurbine\n", - "from floris import FlorisModel\n", - "\n", - "fmodel = FlorisModel(\"defaults\")\n", - "\n", - "time_series = TimeSeries(\n", - " wind_directions=np.array([270.0, 270.0, 280.0]),\n", - " wind_speeds=np.array([8.0, 10.0, 12.0]),\n", - " turbulence_intensities=np.array([0.06, 0.06, 0.06]),\n", - ")\n", - "\n", - "fmodel.set(\n", - " layout_x = [0.0, 500.0],\n", - " layout_y = [0.0, 0.0],\n", - " wind_data=time_series,\n", - ")\n", - "\n", - "fmodel.run()\n", - "\n", - "print(\"Powers [W]:\\n\", fmodel.get_turbine_powers(), \"\\n\")\n", - "print(\"Thrust coefficients [-]:\\n\", fmodel.get_turbine_thrust_coefficients(), \"\\n\")\n", - "print(\"Axial induction factors [-]:\\n\", fmodel.get_turbine_axial_induction_factors(), \"\\n\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c7d9b5ae", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Powers [W]:\n", - " [[ -80385.81346439 35955.07110895]\n", - " [-151917.60066 85753.35035653]\n", - " [-190271.12187713 332785.69634393]] \n", - "\n", - "Thrust coefficients [-]:\n", - " [[0.73380279 0.74621482]\n", - " [0.66198028 0.74239241]\n", - " [0.41175519 0.5029464 ]] \n", - "\n", - "Axial induction factors [-]:\n", - " [[0.34782061 0.35018336]\n", - " [0.30308838 0.35179638]\n", - " [0.18725075 0.22345784]] \n", - "\n" - ] - } - ], - "source": [ - "from floris import FlorisModel, TimeSeries\n", - "\n", - "fmodel = FlorisModel(\"defaults\")\n", - "\n", - "time_series = TimeSeries(\n", - " wind_directions=np.array([270.0, 270.0, 280.0]),\n", - " wind_speeds=np.array([8.0, 10.0, 12.0]),\n", - " turbulence_intensities=np.array([0.06, 0.06, 0.06]),\n", - ")\n", - "\n", - "yaw_angles = np.array([\n", - " [10.0, 0.0], # condition 1\n", - " [10.0, 0.0], # condition 2\n", - " [10.0, 0.0], # condition 3\n", - "])\n", - "\n", - "fmodel.set(\n", - " layout_x = [0.0, 500.0],\n", - " layout_y = [0.0, 0.0],\n", - " wind_data = time_series,\n", - " yaw_angles = yaw_angles\n", - ")\n", - "\n", - "fmodel.set_operation_model(MITRotorTurbine())\n", - "fmodel.run()\n", - "\n", - "print(\"Powers [W]:\\n\", fmodel.get_turbine_powers(), \"\\n\")\n", - "print(\"Thrust coefficients [-]:\\n\", fmodel.get_turbine_thrust_coefficients(), \"\\n\")\n", - "print(\"Axial induction factors [-]:\\n\", fmodel.get_turbine_axial_induction_factors(), \"\\n\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "de761cdd", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "mitrotor-l4Gn_-ln-py3.12", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.11" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/example_05_floris_integration.py b/examples/example_05_floris_integration.py index 093b0cb..71b4c6a 100644 --- a/examples/example_05_floris_integration.py +++ b/examples/example_05_floris_integration.py @@ -1,10 +1,8 @@ -from MITRotor.FlorisInterface.FlorisInterface import csv_to_interp, MITRotorTurbine +import numpy as np from floris import FlorisModel, TimeSeries +from MITRotor.FlorisInterface.FlorisInterface import csv_to_interp, MITRotorTurbine from floris.core.turbine.unified_momentum_model import UnifiedMomentumModelTurbine -import numpy as np -import matplotlib.pyplot as plt -from floris import FlorisModel, TimeSeries fmodel = FlorisModel("defaults") time_series = TimeSeries( @@ -25,9 +23,6 @@ yaw_angles = yaw_angles ) fmodel.set_operation_model(UnifiedMomentumModelTurbine) - -# fmodel.set_operation_model(MITRotorTurbine()) - fmodel.run() print("Powers [W]:\n", fmodel.get_turbine_powers(), "\n") diff --git a/tests/test_floris_interface.py b/tests/test_floris_interface.py new file mode 100644 index 0000000..2d335fb --- /dev/null +++ b/tests/test_floris_interface.py @@ -0,0 +1,118 @@ +import numpy as np +import pytest +from importlib.resources import files +from numpy.testing import assert_almost_equal, assert_allclose +from floris import FlorisModel, TimeSeries +from MITRotor.FlorisInterface import FlorisInterface +from MITRotor.FlorisInterface.FlorisInterface import default_bem_factory, default_pitch_csv, default_tsr_csv +from MITRotor.FlorisInterface.FlorisInterface import MITRotorTurbine, csv_to_interp + + +def test_pitch_tsr_interpolation(): + # get 15MW CSV file paths + pitch_csv = files("MITRotor.FlorisInterface") / "pitch_15mw.csv" + tsr_csv = files("MITRotor.FlorisInterface") / "tsr_15mw.csv" + pitch_csv = str(pitch_csv) + tsr_csv = str(tsr_csv) + # create interpolators + tsr_interp = csv_to_interp(tsr_csv) + pitch_interp = csv_to_interp(pitch_csv) + + # load raw CSV data + tsr_data = np.loadtxt(tsr_csv, delimiter=",", skiprows=1) + pitch_data = np.loadtxt(pitch_csv, delimiter=",", skiprows=1) + tsr_ws, tsr_vals = tsr_data[:, 0], tsr_data[:, 1] + pitch_ws, pitch_vals = pitch_data[:, 0], pitch_data[:, 1] + + # interpolator reproduces raw data + assert_allclose(tsr_interp(tsr_ws), tsr_vals, rtol=1e-12, atol=1e-12) + assert_allclose(pitch_interp(pitch_ws), pitch_vals, rtol=1e-12, atol=1e-12) + + # reasonable values + x_interp_vals = np.linspace(0.0, 25.0, 100) + tsr_interp_vals = tsr_interp(x_interp_vals) + pitch_interp_vals = pitch_interp(x_interp_vals) + assert np.all(np.isfinite(tsr_interp_vals)) + assert np.all(np.isfinite(pitch_interp_vals)) + assert np.all(tsr_interp_vals > 0.0) + assert np.all(pitch_interp_vals >= -10.0) # deg, loose bound + assert np.all(pitch_interp_vals <= 40.0) + + +# compute MITRotor BEM outputs directly +def compute_mitrotor_cp_ct_a(wind_speeds, yaw_deg = 0.0, tilt_deg = 0.0): + bem_model = default_bem_factory() # default BEM (IEA15MW) used in floris interface + pitch_interp = csv_to_interp(default_pitch_csv()) # IEA15MW pitch curve + tsr_interp = csv_to_interp(default_tsr_csv()) # IEA15MW tsr curve + + n = len(wind_speeds) + Ct = np.empty(n) + a = np.empty(n) + for i, ws in enumerate(wind_speeds): + pitch = np.deg2rad(pitch_interp(ws)) + tsr = tsr_interp(ws) + sol = bem_model(pitch, tsr, yaw=np.deg2rad(yaw_deg), tilt = np.deg2rad(tilt_deg)) + Ct[i] = sol.Ct() + a[i] = sol.a() + + return Ct, a + +@pytest.mark.parametrize("n_turbines", [1, 2]) +def test_mitrotor_floris_wind_speeds(n_turbines): + wind_speeds = np.array([6.0, 8.0, 10.0, 12.0]) + wind_dirs = np.full_like(wind_speeds, 270.0) + turbulence_intensity = np.zeros_like(wind_speeds) + + time_series = TimeSeries( + wind_speeds=wind_speeds, + wind_directions=wind_dirs, + turbulence_intensities=turbulence_intensity, + ) + + layout_x = np.linspace(0.0, 500.0 * (n_turbines - 1), n_turbines) + layout_y = np.zeros_like(layout_x) + + fmodel = FlorisModel("defaults") + fmodel.set(layout_x=layout_x, layout_y=layout_y, wind_data=time_series) + fmodel.set_operation_model(MITRotorTurbine()) + + fmodel.run() + + floris_Ct = fmodel.get_turbine_thrust_coefficients() + floris_a = fmodel.get_turbine_axial_induction_factors() + + mit_Ct, mit_a = compute_mitrotor_cp_ct_a(wind_speeds) + + # First turbine matches MITRotor BEM (<1% error) + assert_almost_equal(floris_Ct[:, 0], mit_Ct, decimal=2) + assert_almost_equal(floris_a[:, 0], mit_a, decimal=2) + + if n_turbines > 1: + # first turbine produces more power than the second (wake effects) + floris_power = fmodel.get_turbine_powers() + assert np.all(floris_power[:, 0] > floris_power[:, 1]) + + # yawing the first turbine decreases first turbine power and increases second turbine power + fmodel = FlorisModel("defaults") + yaw_angles = np.tile(np.array([5.0, 0.0]), (4,1)) + fmodel.set(layout_x=layout_x, layout_y=layout_y, wind_data=time_series, yaw_angles = yaw_angles) + fmodel.set_operation_model(MITRotorTurbine()) + fmodel.run() + yawed_floris_power = fmodel.get_turbine_powers() + assert np.all(floris_power[:, 0] > yawed_floris_power[:, 0]) + assert np.all(floris_power[:, 1] < yawed_floris_power[:, 1]) + + # TODO: uncomment if tilt is able to be set for Floris + # tilting the first turbine decreases first turbine power and increases second turbine power + # fmodel = FlorisModel("defaults") + # tilt_angles = np.tile(np.array([5.0, 0.0]), (4,1)) + # fmodel.set(layout_x=layout_x, layout_y=layout_y, wind_data=time_series, tilt_angles = tilt_angles) + # fmodel.set_operation_model(MITRotorTurbine()) + # fmodel.run() + # tilted_floris_power = fmodel.get_turbine_powers() + # assert np.all(floris_power[:, 0] > tilted_floris_power[:, 0]) + # assert np.all(floris_power[:, 1] < tilted_floris_power[:, 1]) + + # # yawing and tilting turbines is equivalent + # assert_almost_equal(yawed_floris_power[:, 0], tilted_floris_power[:, 0], decimal=4) + # assert_almost_equal(yawed_floris_power[:, 1], tilted_floris_power[:, 1], decimal=4) From 6dd4da0578a2b7d4fedd4f42db0903896e02c0a1 Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Wed, 7 Jan 2026 17:41:11 -0500 Subject: [PATCH 05/19] Add files to poetry --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 64e6cc7..8dfd92d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,14 +31,14 @@ matplotlib = "^3.7.3" polars = "^0.19.2" tqdm = "^4.66.1" - [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" - [tool.black] line-length = 120 [tool.ruff] line-length = 120 + +include = ["MITRotor/FlorisInterface/*.csv"] From 71c808ac7f0bd92c2369f779c6a3fcd24e551b8f Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Wed, 7 Jan 2026 17:48:20 -0500 Subject: [PATCH 06/19] Save needed CSV files on GitHub --- .gitignore | 5 +- MITRotor/FlorisInterface/pitch_15mw.csv | 33 +++++++++++++ MITRotor/FlorisInterface/tsr_15mw.csv | 33 +++++++++++++ examples/example_05_floris_integration.py | 9 ++-- poetry.lock | 59 +++++++++++++++++++---- 5 files changed, 124 insertions(+), 15 deletions(-) create mode 100644 MITRotor/FlorisInterface/pitch_15mw.csv create mode 100644 MITRotor/FlorisInterface/tsr_15mw.csv diff --git a/.gitignore b/.gitignore index f729f42..7455b55 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ # Created by https://www.toptal.com/developers/gitignore/api/python # Edit at https://www.toptal.com/developers/gitignore?templates=python - fig fig* *.mat @@ -14,6 +13,10 @@ fig* *.tar *.whl +# Allow these CSVs needed for the floris interface +!MITRotor/FlorisInterface/pitch_15mw.csv +!MITRotor/FlorisInterface/tsr_15mw.csv + ### Python ### # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/MITRotor/FlorisInterface/pitch_15mw.csv b/MITRotor/FlorisInterface/pitch_15mw.csv new file mode 100644 index 0000000..ad33a54 --- /dev/null +++ b/MITRotor/FlorisInterface/pitch_15mw.csv @@ -0,0 +1,33 @@ +wind_speed, pitch +2.9492833517089307, 3.876651982378855 +3.2800441014332966, 3.876651982378855 +3.6990077177508267, 3.876651982378855 +4.117971334068358, 3.436123348017621 +4.911797133406836, 2.8193832599118944 +5.507166482910694, 2.026431718061674 +6.080485115766262, 1.3215859030837005 +6.896361631753032, 0.0881057268722467 +7.844542447629548, 0 +8.7045203969129, 0 +9.432194046306504, 0 +10.115766262403529, 1.8502202643171808 +10.77728776185226, 3.1718061674008813 +11.1742006615215, 3.6123348017621146 +11.637265711135612, 4.845814977973569 +12.078280044101433, 5.991189427312776 +12.717750826901874, 7.48898678414097 +13.864388092613009, 9.60352422907489 +14.547960308710033, 10.748898678414097 +15.231532524807056, 11.718061674008812 +16.245865490628447, 13.215859030837006 +17.039691289966925, 14.273127753303966 +17.723263506063944, 15.154185022026432 +18.362734288864388, 15.947136563876652 +19.04630650496141, 16.740088105726873 +19.906284454244762, 17.709251101321588 +20.45755237045204, 18.325991189427313 +21.604189636163174, 19.559471365638768 +22.640573318632853, 20.61674008810573 +23.721058434399115, 21.762114537444933 +24.40463065049614, 22.46696035242291 +25.02205071664829, 22.995594713656388 \ No newline at end of file diff --git a/MITRotor/FlorisInterface/tsr_15mw.csv b/MITRotor/FlorisInterface/tsr_15mw.csv new file mode 100644 index 0000000..096640a --- /dev/null +++ b/MITRotor/FlorisInterface/tsr_15mw.csv @@ -0,0 +1,33 @@ +wind_speed, tsr +2.993384785005513, 20.792951541850222 +3.2138919514884234, 19.383259911894275 +3.478500551267916, 18.061674008810574 +3.7210584343991178, 16.82819383259912 +4.007717750826902, 15.418502202643174 +4.294377067254686, 14.537444933920705 +4.603087100330761, 13.480176211453745 +4.955898566703418, 12.687224669603525 +5.352811466372657, 11.629955947136564 +5.83792723263506, 10.572687224669604 +6.2348401323043, 9.955947136563877 +6.65380374862183, 9.33920704845815 +7.006615214994487, 8.986784140969164 +7.9547960308710035, 8.986784140969164 +8.880926130099228, 8.81057268722467 +9.807056229327454, 8.986784140969164 +10.689084895259096, 8.986784140969164 +11.681367144432194, 8.370044052863436 +13.114663726571113, 7.312775330396476 +14.283351708930539, 6.607929515418503 +15.143329658213892, 6.255506607929516 +16.245865490628447, 5.814977973568282 +16.863285556780596, 5.638766519823789 +17.67916207276736, 5.462555066079296 +18.80374862183021, 5.110132158590309 +19.928335170893053, 4.845814977973569 +20.87651598676957, 4.581497797356828 +21.49393605292172, 4.493392070484582 +22.39801543550165, 4.229074889867841 +23.16979051819184, 4.052863436123348 +23.96361631753032, 3.9647577092511015 +24.933847850055127, 3.788546255506608 \ No newline at end of file diff --git a/examples/example_05_floris_integration.py b/examples/example_05_floris_integration.py index 71b4c6a..ae3bf2f 100644 --- a/examples/example_05_floris_integration.py +++ b/examples/example_05_floris_integration.py @@ -1,8 +1,9 @@ +import re import numpy as np +from pathlib import Path +import matplotlib.pyplot as plt from floris import FlorisModel, TimeSeries -from MITRotor.FlorisInterface.FlorisInterface import csv_to_interp, MITRotorTurbine -from floris.core.turbine.unified_momentum_model import UnifiedMomentumModelTurbine - +from MITRotor.FlorisInterface.FlorisInterface import csv_to_interp, default_bem_factory, MITRotorTurbine fmodel = FlorisModel("defaults") time_series = TimeSeries( @@ -22,7 +23,7 @@ wind_data = time_series, yaw_angles = yaw_angles ) -fmodel.set_operation_model(UnifiedMomentumModelTurbine) +fmodel.set_operation_model(MITRotorTurbine) fmodel.run() print("Powers [W]:\n", fmodel.get_turbine_powers(), "\n") diff --git a/poetry.lock b/poetry.lock index c90a865..d31bbbb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,14 +2,14 @@ [[package]] name = "anyio" -version = "4.12.0" +version = "4.12.1" description = "High-level concurrency and networking framework on top of asyncio or Trio" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb"}, - {file = "anyio-4.12.0.tar.gz", hash = "sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0"}, + {file = "anyio-4.12.1-py3-none-any.whl", hash = "sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c"}, + {file = "anyio-4.12.1.tar.gz", hash = "sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703"}, ] [package.dependencies] @@ -1511,6 +1511,7 @@ description = "An implementation of JSON Schema validation for Python" optional = false python-versions = ">=3.9" groups = ["dev"] +markers = "python_version < \"3.11\"" files = [ {file = "jsonschema-4.25.1-py3-none-any.whl", hash = "sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63"}, {file = "jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85"}, @@ -1535,6 +1536,38 @@ webcolors = {version = ">=24.6.0", optional = true, markers = "extra == \"format 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" +version = "4.26.0" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.10" +groups = ["dev"] +markers = "python_version >= \"3.11\"" +files = [ + {file = "jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce"}, + {file = "jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +fqdn = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +idna = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +isoduration = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +jsonpointer = {version = ">1.13", optional = true, markers = "extra == \"format-nongpl\""} +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rfc3339-validator = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format-nongpl\""} +rfc3987-syntax = {version = ">=1.1.0", optional = true, markers = "extra == \"format-nongpl\""} +rpds-py = ">=0.25.0" +uri-template = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +webcolors = {version = ">=24.6.0", optional = true, markers = "extra == \"format-nongpl\""} + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "rfc3987-syntax (>=1.1.0)", "uri-template", "webcolors (>=24.6.0)"] + [[package]] name = "jsonschema-specifications" version = "2025.9.1" @@ -3196,16 +3229,22 @@ ppft = ">=1.7.7" [[package]] name = "pathspec" -version = "0.12.1" +version = "1.0.1" description = "Utility library for gitignore style pattern matching of file paths." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, + {file = "pathspec-1.0.1-py3-none-any.whl", hash = "sha256:8870061f22c58e6d83463cfce9a7dd6eca0512c772c1001fb09ac64091816721"}, + {file = "pathspec-1.0.1.tar.gz", hash = "sha256:e2769b508d0dd47b09af6ee2c75b2744a2cb1f474ae4b1494fd6a1b7a841613c"}, ] +[package.extras] +hyperscan = ["hyperscan (>=0.7)"] +optional = ["typing-extensions (>=4)"] +re2 = ["google-re2 (>=1.1)"] +tests = ["pytest (>=9)", "typing-extensions (>=4.15)"] + [[package]] name = "pexpect" version = "4.9.0" @@ -5031,14 +5070,14 @@ dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake [[package]] name = "urllib3" -version = "2.6.2" +version = "2.6.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd"}, - {file = "urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797"}, + {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}, + {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}, ] [package.extras] From b7a69b107f097dc32b6c5f6f1bd5eef7bb65440e Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Wed, 7 Jan 2026 17:53:38 -0500 Subject: [PATCH 07/19] Remove | that isn't python 3.9 compatible --- MITRotor/FlorisInterface/FlorisInterface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MITRotor/FlorisInterface/FlorisInterface.py b/MITRotor/FlorisInterface/FlorisInterface.py index 9d97191..ea717b4 100644 --- a/MITRotor/FlorisInterface/FlorisInterface.py +++ b/MITRotor/FlorisInterface/FlorisInterface.py @@ -1,7 +1,7 @@ import numpy as np import os from attrs import define, field -from typing import Literal, Optional +from typing import Optional from scipy.interpolate import interp1d # FLORIS Imports from floris.type_dec import floris_float_type, NDArrayFloat @@ -78,7 +78,7 @@ def _update_solution(self, yaw_angles: NDArrayFloat, tilt_angles: NDArrayFloat, average_method: str = "cubic-mean", - cubature_weights: NDArrayFloat | None = None, + cubature_weights: Optional[NDArrayFloat] = None, **_, ): # create cache key for current inputs From f696c689af0664c9c0fb97c2e3f45f6dccb40ef5 Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Wed, 7 Jan 2026 17:58:40 -0500 Subject: [PATCH 08/19] Remove non-python 3.9 compatible file call --- tests/test_floris_interface.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/test_floris_interface.py b/tests/test_floris_interface.py index 2d335fb..46f0fe8 100644 --- a/tests/test_floris_interface.py +++ b/tests/test_floris_interface.py @@ -1,6 +1,6 @@ import numpy as np import pytest -from importlib.resources import files +import os from numpy.testing import assert_almost_equal, assert_allclose from floris import FlorisModel, TimeSeries from MITRotor.FlorisInterface import FlorisInterface @@ -10,10 +10,12 @@ def test_pitch_tsr_interpolation(): # get 15MW CSV file paths - pitch_csv = files("MITRotor.FlorisInterface") / "pitch_15mw.csv" - tsr_csv = files("MITRotor.FlorisInterface") / "tsr_15mw.csv" - pitch_csv = str(pitch_csv) - tsr_csv = str(tsr_csv) + module_dir = os.path.dirname(__file__) # tests/ + pitch_csv = os.path.join(module_dir, "..", "MITRotor", "FlorisInterface", "pitch_15mw.csv") + tsr_csv = os.path.join(module_dir, "..", "MITRotor", "FlorisInterface", "tsr_15mw.csv") + pitch_csv = os.path.abspath(pitch_csv) + tsr_csv = os.path.abspath(tsr_csv) + # create interpolators tsr_interp = csv_to_interp(tsr_csv) pitch_interp = csv_to_interp(pitch_csv) From 1a8b424fad05130d331eaccfe1827df1c04fbf96 Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Wed, 7 Jan 2026 19:17:03 -0500 Subject: [PATCH 09/19] Add larger example and clean up comments --- MITRotor/FlorisInterface/FlorisInterface.py | 17 ++- examples/example_05_floris_integration.py | 120 +++++++++++++++++++- 2 files changed, 128 insertions(+), 9 deletions(-) diff --git a/MITRotor/FlorisInterface/FlorisInterface.py b/MITRotor/FlorisInterface/FlorisInterface.py index ea717b4..4358caa 100644 --- a/MITRotor/FlorisInterface/FlorisInterface.py +++ b/MITRotor/FlorisInterface/FlorisInterface.py @@ -14,17 +14,21 @@ from MITRotor.BEMSolver import BEM from UnifiedMomentumModel.Utilities.Geometry import calc_eff_yaw +# default rotor if none provided by user (IEA 15MW) def default_bem_factory(): return BEM( rotor=IEA15MW(), momentum_model=UnifiedMomentum(averaging="rotor"), geometry=BEMGeometry(Nr=10, Ntheta=20), ) - +# pitch vs windspeed curve if none provided by user +# for IEA 15MW from figure 2 (https://docs.nrel.gov/docs/fy22osti/82134.pdf) def default_pitch_csv(): module_dir = os.path.dirname(__file__) return os.path.join(module_dir, "pitch_15mw.csv") +# tsr vs windspeed curve if none provided by user +# for IEA 15MW from figure 2 (https://docs.nrel.gov/docs/fy22osti/82134.pdf) def default_tsr_csv(): module_dir = os.path.dirname(__file__) return os.path.join(module_dir, "tsr_15mw.csv") @@ -40,7 +44,7 @@ def csv_to_interp(csv_file): x = x[idx] y = y[idx] # return interpolator for y - return interp1d(x, y, kind="linear", fill_value="extrapolate", bounds_error=False) + return interp1d(x, y, kind="linear", fill_value="extrapolate", bounds_error=False) # TODO: should fill_value be extrapolate? @define class MITRotorTurbine(BaseOperationModel): @@ -65,11 +69,12 @@ class MITRotorTurbine(BaseOperationModel): _power = field(init=False, default=None, type = NDArrayFloat) def __attrs_post_init__(self): + # creates interpolation objects self._pitch_interp = csv_to_interp(self.pitch_csv) self._tsr_interp = csv_to_interp(self.tsr_csv) def _get_state_key(self, velocities: np.ndarray, yaw_angles: np.ndarray, tilt_angles: np.ndarray) -> tuple: - # Fast, deterministic, and explicit + # saves key to uniquely identify farm state -> avoids re-solving for calls to power, thrust, and induction for same state return velocities.tobytes(), yaw_angles.tobytes(), tilt_angles.tobytes() def _update_solution(self, @@ -82,7 +87,7 @@ def _update_solution(self, **_, ): # create cache key for current inputs - key = self._get_state_key(velocities, yaw_angles, tilt_angles) # TODO: add more inputs + key = self._get_state_key(velocities, yaw_angles, tilt_angles) # update solution if conditions are different if key != self._last_key: n_findex, n_turbines = yaw_angles.shape @@ -99,9 +104,11 @@ def _update_solution(self, method=average_method, cubature_weights=cubature_weights, ) + # calculate rotor area rotor_area = np.pi * self.bem_model.rotor.R**2 - # loop over flow conditions + + # loop over flow conditions -> TODO: should this be vectorized? for findex in range(n_findex): for tindex in range(n_turbines): # get setpoints diff --git a/examples/example_05_floris_integration.py b/examples/example_05_floris_integration.py index ae3bf2f..fd8aeb2 100644 --- a/examples/example_05_floris_integration.py +++ b/examples/example_05_floris_integration.py @@ -1,10 +1,14 @@ -import re import numpy as np +import os from pathlib import Path import matplotlib.pyplot as plt +from matplotlib import cm +from matplotlib.colors import Normalize +from matplotlib.cm import ScalarMappable from floris import FlorisModel, TimeSeries from MITRotor.FlorisInterface.FlorisInterface import csv_to_interp, default_bem_factory, MITRotorTurbine +# ------------------ run basic case -------------------------------------------------------- fmodel = FlorisModel("defaults") time_series = TimeSeries( wind_directions=np.array([270.0, 270.0, 280.0]), @@ -23,9 +27,117 @@ wind_data = time_series, yaw_angles = yaw_angles ) -fmodel.set_operation_model(MITRotorTurbine) +fmodel.set_operation_model(MITRotorTurbine()) fmodel.run() - print("Powers [W]:\n", fmodel.get_turbine_powers(), "\n") print("Thrust coefficients [-]:\n", fmodel.get_turbine_thrust_coefficients(), "\n") -print("Axial induction factors [-]:\n", fmodel.get_turbine_axial_induction_factors(), "\n") \ No newline at end of file +print("Axial induction factors [-]:\n", fmodel.get_turbine_axial_induction_factors(), "\n") + +# -------------------- plot pitch and tsr control curves, as well as CT for IEA15MW ------------------ +module_dir = os.path.dirname(__file__) # examples/ +csv_dir = os.path.join(module_dir, "..", "MITRotor", "FlorisInterface") + +wind_speeds = np.linspace(5, 25.0, 20) +wind_dirs = np.full_like(wind_speeds, 270.0) +turbulence_intensity = np.zeros_like(wind_speeds) + +# plot pitch and tsr control curves for IEA15MW from figure 2 (https://docs.nrel.gov/docs/fy22osti/82134.pdf) +pitch_csv = os.path.join(csv_dir, "pitch_15mw.csv") +tsr_csv = os.path.join(csv_dir, "tsr_15mw.csv") +pitch_interp = csv_to_interp(pitch_csv) +tsr_interp = csv_to_interp(tsr_csv) + +# plot interpolated pitch and tsr data +fig, ax = plt.subplots(figsize=(8, 6)) +ax.scatter( + wind_speeds, + pitch_interp(wind_speeds), + s=40, + edgecolors="k", + label = "Interpolated Pitch [deg]" +) +ax.scatter( + wind_speeds, + tsr_interp(wind_speeds), + s=40, + edgecolors="k", + label = "Interpolated Tip-Speed Ratio [-]" +) + +# load and plot raw CSV data +tsr_data = np.loadtxt(tsr_csv, delimiter=",", skiprows=1) +pitch_data = np.loadtxt(pitch_csv, delimiter=",", skiprows=1) +tsr_ws, tsr_vals = tsr_data[:, 0], tsr_data[:, 1] +pitch_ws, pitch_vals = pitch_data[:, 0], pitch_data[:, 1] +ax.plot( + pitch_ws, + pitch_vals, + label = "Pitch [deg]" +) +ax.plot( + tsr_ws, + tsr_vals, + label = "Tip-Speed Ratio [-]" +) +ax.set_xlabel("Wind Speed [m/s]") +ax.set_title("IEA 15MW: Fixed Bottom Trajectories") +plt.legend() + +# compute CT from floris +fmodel = FlorisModel("defaults") + +time_series = TimeSeries( + wind_speeds=wind_speeds, + wind_directions=wind_dirs, + turbulence_intensities=turbulence_intensity, +) + +fmodel.set(layout_x = [0.0], layout_y = [0.0], wind_data = time_series) +fmodel.set_operation_model(MITRotorTurbine()) +fmodel.run() +floris_Ct = fmodel.get_turbine_thrust_coefficients() + +fig, ax = plt.subplots(figsize=(8, 6)) +cmap = cm.viridis + +# plot setpoint curves for IEA15MW from figure 3.2 (https://docs.nrel.gov/docs/fy20osti/75698.pdf) +setpoint_curves = os.path.join(csv_dir, "pitch_tsr_ct_15mw.csv") +data = np.loadtxt(setpoint_curves, delimiter=",", skiprows=1) +all_cts = np.concatenate([data[:, 2], floris_Ct.flatten()]) +norm = Normalize(vmin=all_cts.min(), vmax=all_cts.max()) + +for ct in np.unique(data[:, 2]): + mask = data[:, 2] == ct + ax.plot( + data[mask, 0], + data[mask, 1], + color=cmap(norm(ct)), + linewidth=2, + label=f"Ct ≈ {ct:.3f}", + ) + +# plot FLORIS points +sc = ax.scatter( + pitch_interp(wind_speeds), + tsr_interp(wind_speeds), + c=floris_Ct, + cmap=cmap, + norm=norm, + s=40, + edgecolors="k", + label = "FLORIS with MITRotor" +) + +# colorbar that covers all Ct values +sm = ScalarMappable(norm=norm, cmap=cmap) +sm.set_array([]) +plt.colorbar(sm, ax=ax, label="$C_T$") + +# label plot +ax.set_xlabel("Pitch [deg]") +ax.set_ylabel("Tip-Speed Ratio [-]") +ax.set_title("IEA 15MW: $C_T$ Control Curves vs FLORIS/MITRotor") +ax.grid(True, alpha=0.3) +ax.legend(fontsize=9) +plt.tight_layout() +plt.show() From 92d3cda6e88c529e9860dbfb0cb11f82fb0e7493 Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Wed, 7 Jan 2026 19:35:33 -0500 Subject: [PATCH 10/19] Add docstring --- MITRotor/FlorisInterface/FlorisInterface.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/MITRotor/FlorisInterface/FlorisInterface.py b/MITRotor/FlorisInterface/FlorisInterface.py index 4358caa..2ccdf26 100644 --- a/MITRotor/FlorisInterface/FlorisInterface.py +++ b/MITRotor/FlorisInterface/FlorisInterface.py @@ -49,7 +49,17 @@ def csv_to_interp(csv_file): @define class MITRotorTurbine(BaseOperationModel): """ - A turbine operation model that calls MITRotor. + Turbine operation model as described by Liew et al. (2024). + + Args: + bem_model (BEM): optional BEM model as defined in MITRotor, defaults to IEA15MW with UMM momentum model + pitch_csv (str): optional path to pitch trajectory based on wind speed, defaults to IEA15MW Figure 2 (https://docs.nrel.gov/docs/fy22osti/82134.pdf) + tsr_csv (str)): optional path to tsr trajectory based on wind speed, defaults to IEA15MW Figure 2 (https://docs.nrel.gov/docs/fy22osti/82134.pdf) + + Methods: + power + thrust_coefficient + axial_induction """ # user can define a BEM model if they want a different rotor, momentum model, or geometry bem_model = field(init = True, factory = default_bem_factory, type = BEM) From d4b2d1d5f215387aa480e783579d7606ad6c193e Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Thu, 8 Jan 2026 13:22:01 -0500 Subject: [PATCH 11/19] Add CT CSV file for IEA15MW --- .gitignore | 1 + .../FlorisInterface/pitch_tsr_ct_15mw.csv | 56 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 MITRotor/FlorisInterface/pitch_tsr_ct_15mw.csv diff --git a/.gitignore b/.gitignore index 7455b55..646f286 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ fig* # Allow these CSVs needed for the floris interface !MITRotor/FlorisInterface/pitch_15mw.csv !MITRotor/FlorisInterface/tsr_15mw.csv +!MITRotor/FlorisInterface/pitch_tsr_ct_15mw.csv ### Python ### # Byte-compiled / optimized / DLL files diff --git a/MITRotor/FlorisInterface/pitch_tsr_ct_15mw.csv b/MITRotor/FlorisInterface/pitch_tsr_ct_15mw.csv new file mode 100644 index 0000000..47c23f4 --- /dev/null +++ b/MITRotor/FlorisInterface/pitch_tsr_ct_15mw.csv @@ -0,0 +1,56 @@ +pitch,tsr,Ct +-4.952153,7.140505,0.750000 +-4.529506,7.166850,0.750000 +-4.130781,7.210757,0.750000 +-3.740032,7.254665,0.750000 +-3.325359,7.316136,0.750000 +-3.038278,7.364435,0.750000 +-2.655502,7.443469,0.750000 +-2.185008,7.553238,0.750000 +-1.866029,7.645445,0.750000 +-1.491228,7.759605,0.750000 +-1.180223,7.878156,0.750000 +-0.837321,8.014270,0.750000 +-0.454545,8.194292,0.750000 +-0.119617,8.365532,0.750000 +0.199362,8.545554,0.750000 +0.486443,8.729967,0.750000 +0.757576,8.927552,0.750000 +0.996810,9.111965,0.750000 +1.299841,9.371021,0.750000 +1.531100,9.586169,0.750000 +1.858054,9.924259,0.750000 +-4.904306,8.163557,0.900000 +-4.577352,8.225027,0.900000 +-4.242424,8.321625,0.900000 +-3.827751,8.444566,0.900000 +-3.460925,8.567508,0.900000 +-3.133971,8.699232,0.900000 +-2.759171,8.857300,0.900000 +-2.448166,8.997805,0.900000 +-2.105263,9.173436,0.900000 +-1.778309,9.353458,0.900000 +-1.395534,9.572997,0.900000 +-1.076555,9.788145,0.900000 +-0.781499,10.007684,0.900000 +-4.920255,9.353458,1.050000 +-4.649123,9.454446,1.050000 +-4.330144,9.599341,1.050000 +-4.082935,9.717892,1.050000 +-3.819777,9.845225,1.050000 +-3.548644,9.994512,1.050000 +-3.261563,10.152580,1.050000 +0.805423,7.030735,0.600000 +1.156300,7.171240,0.600000 +1.555024,7.355653,0.600000 +1.913876,7.548847,0.600000 +2.232855,7.742042,0.600000 +2.511962,7.952799,0.600000 +2.799043,8.194292,0.600000 +3.046252,8.418222,0.600000 +3.269537,8.655324,0.600000 +3.484848,8.892426,0.600000 +3.668262,9.155873,0.600000 +3.859649,9.410538,0.600000 +4.003190,9.656422,0.600000 +4.146730,9.941822,0.600000 From 6688d21428cb8ab4be981c86d2820c3e2b70c750 Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Tue, 20 Jan 2026 17:25:30 -0500 Subject: [PATCH 12/19] Use more condensed validation data and improve validation figures --- .gitignore | 6 +- MITRotor/FlorisInterface/FlorisInterface.py | 64 +++---- MITRotor/FlorisInterface/IEA_15mw_rotor.csv | 51 ++++++ MITRotor/FlorisInterface/pitch_15mw.csv | 33 ---- .../FlorisInterface/pitch_tsr_ct_15mw.csv | 56 ------ MITRotor/FlorisInterface/tsr_15mw.csv | 33 ---- MITRotor/Momentum.py | 8 +- examples/example_05_floris_integration.py | 168 +++++++++++------- tests/test_floris_interface.py | 39 ++-- 9 files changed, 203 insertions(+), 255 deletions(-) create mode 100644 MITRotor/FlorisInterface/IEA_15mw_rotor.csv delete mode 100644 MITRotor/FlorisInterface/pitch_15mw.csv delete mode 100644 MITRotor/FlorisInterface/pitch_tsr_ct_15mw.csv delete mode 100644 MITRotor/FlorisInterface/tsr_15mw.csv diff --git a/.gitignore b/.gitignore index 646f286..272610c 100644 --- a/.gitignore +++ b/.gitignore @@ -14,9 +14,9 @@ fig* *.whl # Allow these CSVs needed for the floris interface -!MITRotor/FlorisInterface/pitch_15mw.csv -!MITRotor/FlorisInterface/tsr_15mw.csv -!MITRotor/FlorisInterface/pitch_tsr_ct_15mw.csv +!MITRotor/FlorisInterface/IEA_15mw_rotor.csv + +Validation/ ### Python ### # Byte-compiled / optimized / DLL files diff --git a/MITRotor/FlorisInterface/FlorisInterface.py b/MITRotor/FlorisInterface/FlorisInterface.py index 2ccdf26..0d96c5e 100644 --- a/MITRotor/FlorisInterface/FlorisInterface.py +++ b/MITRotor/FlorisInterface/FlorisInterface.py @@ -1,5 +1,6 @@ -import numpy as np import os +import numpy as np +import polars as pl from attrs import define, field from typing import Optional from scipy.interpolate import interp1d @@ -9,8 +10,9 @@ from floris.core.rotor_velocity import average_velocity, rotor_velocity_air_density_correction # MITRotor / UMM Imports from MITRotor.ReferenceTurbines import IEA15MW -from MITRotor.Momentum import UnifiedMomentum +from MITRotor.Momentum import MadsenMomentum from MITRotor.Geometry import BEMGeometry +from MITRotor.TipLoss import NoTipLoss from MITRotor.BEMSolver import BEM from UnifiedMomentumModel.Utilities.Geometry import calc_eff_yaw @@ -18,33 +20,32 @@ def default_bem_factory(): return BEM( rotor=IEA15MW(), - momentum_model=UnifiedMomentum(averaging="rotor"), + momentum_model=MadsenMomentum(averaging="annulus"), geometry=BEMGeometry(Nr=10, Ntheta=20), + tiploss_model=NoTipLoss() ) -# pitch vs windspeed curve if none provided by user +# pitch vs windspeed interpolater if none provided by user # for IEA 15MW from figure 2 (https://docs.nrel.gov/docs/fy22osti/82134.pdf) -def default_pitch_csv(): +def default_pitch_interp(): module_dir = os.path.dirname(__file__) - return os.path.join(module_dir, "pitch_15mw.csv") - -# tsr vs windspeed curve if none provided by user + pitch_file = os.path.join(module_dir, "IEA_15mw_rotor.csv") + df = pl.read_csv(pitch_file) + wind_table = df["Wind [m/s]"].to_numpy() + pitch_table = df["Pitch [deg]"].to_numpy() + # TODO: should fill_value be extrapolate? + return interp1d(wind_table, pitch_table, kind="linear", fill_value="extrapolate", bounds_error=False) + +# tsr vs windspeed interpolater if none provided by user # for IEA 15MW from figure 2 (https://docs.nrel.gov/docs/fy22osti/82134.pdf) -def default_tsr_csv(): +def default_tsr_interp(): module_dir = os.path.dirname(__file__) - return os.path.join(module_dir, "tsr_15mw.csv") - -def csv_to_interp(csv_file): - # read in csv - data = np.loadtxt(csv_file, delimiter=",", skiprows=1) - # split data into x (wind speed) and y (either pitch or tsr) - x = data[:, 0] - y = data[:, 1] - # sort by x (wind speed) - idx = np.argsort(x) - x = x[idx] - y = y[idx] - # return interpolator for y - return interp1d(x, y, kind="linear", fill_value="extrapolate", bounds_error=False) # TODO: should fill_value be extrapolate? + tsr_file = os.path.join(module_dir, "IEA_15mw_rotor.csv") + df = pl.read_csv(tsr_file) + wind_table = df["Wind [m/s]"].to_numpy() + tip_speed_table = df["Tip Speed [m/s]"].to_numpy() + tsr_table = tip_speed_table / wind_table + # TODO: should fill_value be extrapolate? + return interp1d(wind_table, tsr_table, kind="linear", fill_value="extrapolate", bounds_error=False) @define class MITRotorTurbine(BaseOperationModel): @@ -64,13 +65,9 @@ class MITRotorTurbine(BaseOperationModel): # user can define a BEM model if they want a different rotor, momentum model, or geometry bem_model = field(init = True, factory = default_bem_factory, type = BEM) - # user can define csv paths for pitch and tsr values - pitch_csv = field(init = True, factory = default_pitch_csv, type = str) - tsr_csv = field(init = True, factory = default_tsr_csv, type = str) - # create interp objects based on pitch and tsr csvs - _pitch_interp = field(init=False, default=None, type = interp1d, repr = False) - _tsr_interp = field(init=False, default=None, type = interp1d, repr = False) + pitch_interp = field(init=True, factory=default_pitch_interp, type = interp1d, repr = False) + tsr_interp = field(init=True, factory=default_tsr_interp, type = interp1d, repr = False) # save most recent solution by unique floris arguments _last_key = field(init=False, default=None, type = bytes) @@ -78,11 +75,6 @@ class MITRotorTurbine(BaseOperationModel): _Ct = field(init=False, default=None, type = NDArrayFloat) _power = field(init=False, default=None, type = NDArrayFloat) - def __attrs_post_init__(self): - # creates interpolation objects - self._pitch_interp = csv_to_interp(self.pitch_csv) - self._tsr_interp = csv_to_interp(self.tsr_csv) - def _get_state_key(self, velocities: np.ndarray, yaw_angles: np.ndarray, tilt_angles: np.ndarray) -> tuple: # saves key to uniquely identify farm state -> avoids re-solving for calls to power, thrust, and induction for same state return velocities.tobytes(), yaw_angles.tobytes(), tilt_angles.tobytes() @@ -124,8 +116,8 @@ def _update_solution(self, # get setpoints vel = rotor_average_velocities[findex, tindex] yaw, tilt = np.deg2rad(yaw_angles[findex, tindex]), np.deg2rad(tilt_angles[findex, tindex]) - pitch = np.deg2rad(self._pitch_interp(vel)) - tsr = self._tsr_interp(vel) + pitch = np.deg2rad(self.pitch_interp(vel)) + tsr = self.tsr_interp(vel) # solve BEM bem_sol = self.bem_model(pitch, tsr, yaw = yaw, tilt = tilt) # get induction and thrust coeff diff --git a/MITRotor/FlorisInterface/IEA_15mw_rotor.csv b/MITRotor/FlorisInterface/IEA_15mw_rotor.csv new file mode 100644 index 0000000..c5ce68c --- /dev/null +++ b/MITRotor/FlorisInterface/IEA_15mw_rotor.csv @@ -0,0 +1,51 @@ +Wind [m/s],Pitch [deg],Power [MW],Power Coefficient [-],Aero Power Coefficient [-],Rotor Speed [rpm],Tip Speed [m/s],Thrust [MN],Thrust Coefficient [-],Torque [MNm],Torque Coefficient [-],Blade Moment [MNm],Blade Moment Coefficient [-] +3,3.920293066,0.042500121,0.056434434,0.05897929,5,63.33974388,0.202909425,0.808309128,0.0848295,0.002806784,5.980185544,0.197868559 +3.54953237,3.913016973,0.292273273,0.234311418,0.244877465,5,63.33974388,0.275784048,0.784774049,0.583372359,0.01378822,7.854972515,0.185655162 +4.067900771,3.709535473,0.607683429,0.323656337,0.338251306,5,63.33974388,0.360568653,0.781205046,1.212925534,0.021827203,10.04565323,0.180776562 +4.553906848,3.347852063,0.980824467,0.372354525,0.389145491,5,63.33974388,0.454006762,0.784895445,1.957708542,0.028111524,12.46569389,0.178999911 +5.006427063,2.905271743,1.401604341,0.400460354,0.418518725,5,63.33974388,0.550743112,0.787791082,2.797577836,0.033237705,14.97412576,0.177905892 +5.424415288,2.410742282,1.858097567,0.41737602,0.436197187,5,63.33974388,0.648091847,0.789675144,3.708730359,0.03753393,17.50236286,0.177131362 +5.806905228,1.897891096,2.33681832,0.42786672,0.447160954,5,63.33974388,0.743097627,0.790085645,4.66424864,0.041190481,19.97338486,0.176387107 +6.153012649,1.38709008,2.823250666,0.434514015,0.454108003,5,63.33974388,0.833653636,0.789455775,5.635159124,0.044323619,22.33283369,0.175659992 +6.461937428,0.891713024,3.302257138,0.438773526,0.458559593,5,63.33974388,0.918175231,0.78834778,6.591247694,0.047005295,24.54016065,0.175007454 +6.732965398,0.425207394,3.758708724,0.441506699,0.461416015,5,63.33974388,0.995161603,0.787043287,7.502317104,0.049281883,26.55670159,0.174448007 +6.965470002,0.000469162,4.17814357,0.443251132,0.463239112,5,63.33974388,1.063280746,0.785714686,8.339501745,0.05118514,28.34690587,0.173984056 +7.158913742,0,4.546959581,0.444321653,0.46363055,5.086081797,64.43022368,1.11334287,0.778847528,8.908071675,0.051759978,29.65857718,0.172329924 +7.312849418,0,4.855095716,0.445098035,0.46363055,5.195446076,65.81564476,1.161737302,0.778847528,9.295284892,0.051759978,30.94776674,0.172329924 +7.426921164,0,5.091278414,0.445572294,0.46363055,5.27648885,66.84229047,1.198263417,0.778847528,9.587537406,0.051759978,31.92079369,0.172329924 +7.500865272,0,5.248186603,0.445854287,0.46363055,5.329022767,67.50778745,1.22224256,0.778847528,9.779399169,0.051759978,32.55957918,0.172329924 +7.534510799,0,5.320523056,0.445971313,0.46363055,5.35292638,67.81059719,1.233232019,0.778847528,9.867327955,0.051759978,32.8523297,0.172329924 +7.541241633,0,5.335074621,0.445994704,0.46363055,5.357708331,67.8711747,1.23543638,0.778847528,9.884965469,0.051759978,32.91105213,0.172329924 +7.58833327,0,5.437629628,0.44615751,0.46363055,5.391164791,68.29499943,1.250914035,0.778847528,10.00880519,0.051759978,33.32336468,0.172329924 +7.675676842,0,5.630967375,0.446427293,0.46363055,5.453218417,69.08109158,1.279876417,0.778847528,10.2405388,0.051759978,34.09489971,0.172329924 +7.803070431,0,5.920680499,0.446779068,0.46363055,5.543725753,70.22763388,1.322713319,0.778847528,10.58328514,0.051759978,35.23604104,0.172329924 +7.970219531,0,6.314795749,0.44716338,0.46363055,5.662477568,71.73197578,1.379987779,0.778847528,11.04154918,0.051759978,36.76178755,0.172329924 +8.176737731,0,6.824124693,0.447532442,0.46363055,5.809199332,73.59063957,1.452428655,0.778847528,11.62116264,0.051759978,38.69155545,0.172329924 +8.422147605,0,7.462468983,0.447849163,0.46363055,5.983551858,75.79932844,1.540920985,0.778847528,12.3292069,0.051759978,41.04892142,0.172329924 +8.70588182,0,8.237943086,0.447608431,0.46363055,6.185132081,78.35293638,1.646494209,0.778847528,13.17391868,0.051759978,43.86130896,0.172329924 +9.027284445,0,9.167503057,0.446783839,0.46363055,6.413473991,81.24556,1.770308387,0.778847528,14.16457987,0.051759978,47.15962114,0.172329924 +9.385612468,0,10.28468981,0.445985887,0.46363055,6.668049714,84.47051221,1.913638541,0.778847528,15.31139216,0.051759978,50.97782356,0.172329924 +9.780037514,0,11.61664761,0.44522242,0.46363055,6.948270725,88.02033763,2.077857279,0.778847528,16.62533805,0.051759978,55.3524814,0.172329924 +10.20964776,0,13.19374497,0.444481389,0.46363055,7.253489215,91.88682983,2.264415873,0.778847528,18.11802945,0.051759978,60.3222554,0.172329924 +10.65843263,0,15,0.444149321,0.463833394,7.499240933,95,2.447339849,0.772369945,19.94703495,0.05228731,65.14869599,0.170774759 +10.67345004,0.511974392,15.00000265,0.442277294,0.461878402,7.499240933,95,2.374311052,0.74721528,19.9470383,0.052140287,63.06741054,0.164854194 +11.17037214,3.723733263,14.99997215,0.385838268,0.402938078,7.499240933,95,1.956901748,0.562278542,19.94699774,0.047604378,50.90543244,0.12148803 +11.6992653,5.396486368,15.00000888,0.33584085,0.350724844,7.499240933,95,1.769139016,0.463406962,19.94704659,0.043397635,45.21424327,0.098370013 +12.25890683,6.766694447,15.00000059,0.291913256,0.304850441,7.499240933,95,1.630599159,0.389010657,19.94703557,0.039525695,40.89463241,0.081034035 +12.84800295,7.989590009,15.0000001,0.2535725,0.264810476,7.499240933,95,1.518234459,0.329750424,19.94703492,0.03598419,37.29572857,0.067281007 +13.46519181,9.124292675,14.99994632,0.220277351,0.230039733,7.499240933,95,1.423067352,0.281396143,19.9469634,0.032760939,34.16497221,0.05611263 +14.10904661,10.20005088,15.00008104,0.191477776,0.199963801,7.499240933,95,1.340503102,0.241429458,19.94714255,0.029839394,31.37410139,0.046933247 +14.77807889,11.23370987,15.00005146,0.166631299,0.174016164,7.499240933,95,1.267744754,0.208119912,19.94710322,0.027198723,28.84591141,0.039332626 +15.470742,12.23548853,15.00003481,0.145236779,0.151673469,7.499240933,95,1.20299036,0.180201181,19.94708107,0.02481771,26.53102258,0.033009302 +16.18543466,13.21207233,15.00002476,0.12683428,0.132455397,7.499240933,95,1.144953313,0.156695606,19.94706771,0.022674357,24.39444366,0.027729806 +16.92050464,14.16785471,15.00001806,0.111011922,0.115931814,7.499240933,95,1.092675034,0.136830266,19.9470588,0.020747076,22.41059375,0.023309415 +17.67425264,15.10569973,15.00001315,0.097406118,0.101723021,7.499240933,95,1.045410488,0.119983771,19.94705227,0.019015215,20.56016302,0.019599684 +18.44493615,16.02744622,15.00000923,0.08569941,0.089497487,7.499240933,95,1.002561347,0.105651196,19.94704705,0.017459385,18.82803369,0.016479927 +19.23077353,16.93422766,15.000006,0.075616913,0.078968149,7.499240933,95,0.963634907,0.093419339,19.94704276,0.016061631,17.20197892,0.013851268 +20.02994808,17.82668205,15.00000341,0.066922115,0.069888009,7.499240933,95,0.928217511,0.082948375,19.94703931,0.014805512,15.6718209,0.011632269 +20.8406123,18.70508213,15.00000149,0.059412476,0.062045553,7.499240933,95,0.895956018,0.07395772,19.94703676,0.013676094,14.22892793,0.009755642 +21.66089211,19.56943768,15.00000033,0.052915149,0.055260274,7.499240933,95,0.866544894,0.066214966,19.94703522,0.012659901,12.8658372,0.008165636 +22.4888912,20.41950905,15.00018216,0.047283561,0.049379102,7.499240933,95,0.839725354,0.059527679,19.94727702,0.011744977,11.57634071,0.006816161 +23.32269542,21.25504455,15.00000054,0.042390918,0.044269624,7.499240933,95,0.815233262,0.053733135,19.9470355,0.010920072,10.35411323,0.005668395 +24.1603772,22.07544699,15.00000177,0.038132735,0.039822724,7.499240933,95,0.79288419,0.048699008,19.94703713,0.010175965,9.195130033,0.004690888 +25,22.88018135,15.0000035,0.034418276,0.035943645,7.499240933,95,0.772480289,0.044312389,19.94703943,0.009503927,8.095078123,0.003856965 \ No newline at end of file diff --git a/MITRotor/FlorisInterface/pitch_15mw.csv b/MITRotor/FlorisInterface/pitch_15mw.csv deleted file mode 100644 index ad33a54..0000000 --- a/MITRotor/FlorisInterface/pitch_15mw.csv +++ /dev/null @@ -1,33 +0,0 @@ -wind_speed, pitch -2.9492833517089307, 3.876651982378855 -3.2800441014332966, 3.876651982378855 -3.6990077177508267, 3.876651982378855 -4.117971334068358, 3.436123348017621 -4.911797133406836, 2.8193832599118944 -5.507166482910694, 2.026431718061674 -6.080485115766262, 1.3215859030837005 -6.896361631753032, 0.0881057268722467 -7.844542447629548, 0 -8.7045203969129, 0 -9.432194046306504, 0 -10.115766262403529, 1.8502202643171808 -10.77728776185226, 3.1718061674008813 -11.1742006615215, 3.6123348017621146 -11.637265711135612, 4.845814977973569 -12.078280044101433, 5.991189427312776 -12.717750826901874, 7.48898678414097 -13.864388092613009, 9.60352422907489 -14.547960308710033, 10.748898678414097 -15.231532524807056, 11.718061674008812 -16.245865490628447, 13.215859030837006 -17.039691289966925, 14.273127753303966 -17.723263506063944, 15.154185022026432 -18.362734288864388, 15.947136563876652 -19.04630650496141, 16.740088105726873 -19.906284454244762, 17.709251101321588 -20.45755237045204, 18.325991189427313 -21.604189636163174, 19.559471365638768 -22.640573318632853, 20.61674008810573 -23.721058434399115, 21.762114537444933 -24.40463065049614, 22.46696035242291 -25.02205071664829, 22.995594713656388 \ No newline at end of file diff --git a/MITRotor/FlorisInterface/pitch_tsr_ct_15mw.csv b/MITRotor/FlorisInterface/pitch_tsr_ct_15mw.csv deleted file mode 100644 index 47c23f4..0000000 --- a/MITRotor/FlorisInterface/pitch_tsr_ct_15mw.csv +++ /dev/null @@ -1,56 +0,0 @@ -pitch,tsr,Ct --4.952153,7.140505,0.750000 --4.529506,7.166850,0.750000 --4.130781,7.210757,0.750000 --3.740032,7.254665,0.750000 --3.325359,7.316136,0.750000 --3.038278,7.364435,0.750000 --2.655502,7.443469,0.750000 --2.185008,7.553238,0.750000 --1.866029,7.645445,0.750000 --1.491228,7.759605,0.750000 --1.180223,7.878156,0.750000 --0.837321,8.014270,0.750000 --0.454545,8.194292,0.750000 --0.119617,8.365532,0.750000 -0.199362,8.545554,0.750000 -0.486443,8.729967,0.750000 -0.757576,8.927552,0.750000 -0.996810,9.111965,0.750000 -1.299841,9.371021,0.750000 -1.531100,9.586169,0.750000 -1.858054,9.924259,0.750000 --4.904306,8.163557,0.900000 --4.577352,8.225027,0.900000 --4.242424,8.321625,0.900000 --3.827751,8.444566,0.900000 --3.460925,8.567508,0.900000 --3.133971,8.699232,0.900000 --2.759171,8.857300,0.900000 --2.448166,8.997805,0.900000 --2.105263,9.173436,0.900000 --1.778309,9.353458,0.900000 --1.395534,9.572997,0.900000 --1.076555,9.788145,0.900000 --0.781499,10.007684,0.900000 --4.920255,9.353458,1.050000 --4.649123,9.454446,1.050000 --4.330144,9.599341,1.050000 --4.082935,9.717892,1.050000 --3.819777,9.845225,1.050000 --3.548644,9.994512,1.050000 --3.261563,10.152580,1.050000 -0.805423,7.030735,0.600000 -1.156300,7.171240,0.600000 -1.555024,7.355653,0.600000 -1.913876,7.548847,0.600000 -2.232855,7.742042,0.600000 -2.511962,7.952799,0.600000 -2.799043,8.194292,0.600000 -3.046252,8.418222,0.600000 -3.269537,8.655324,0.600000 -3.484848,8.892426,0.600000 -3.668262,9.155873,0.600000 -3.859649,9.410538,0.600000 -4.003190,9.656422,0.600000 -4.146730,9.941822,0.600000 diff --git a/MITRotor/FlorisInterface/tsr_15mw.csv b/MITRotor/FlorisInterface/tsr_15mw.csv deleted file mode 100644 index 096640a..0000000 --- a/MITRotor/FlorisInterface/tsr_15mw.csv +++ /dev/null @@ -1,33 +0,0 @@ -wind_speed, tsr -2.993384785005513, 20.792951541850222 -3.2138919514884234, 19.383259911894275 -3.478500551267916, 18.061674008810574 -3.7210584343991178, 16.82819383259912 -4.007717750826902, 15.418502202643174 -4.294377067254686, 14.537444933920705 -4.603087100330761, 13.480176211453745 -4.955898566703418, 12.687224669603525 -5.352811466372657, 11.629955947136564 -5.83792723263506, 10.572687224669604 -6.2348401323043, 9.955947136563877 -6.65380374862183, 9.33920704845815 -7.006615214994487, 8.986784140969164 -7.9547960308710035, 8.986784140969164 -8.880926130099228, 8.81057268722467 -9.807056229327454, 8.986784140969164 -10.689084895259096, 8.986784140969164 -11.681367144432194, 8.370044052863436 -13.114663726571113, 7.312775330396476 -14.283351708930539, 6.607929515418503 -15.143329658213892, 6.255506607929516 -16.245865490628447, 5.814977973568282 -16.863285556780596, 5.638766519823789 -17.67916207276736, 5.462555066079296 -18.80374862183021, 5.110132158590309 -19.928335170893053, 4.845814977973569 -20.87651598676957, 4.581497797356828 -21.49393605292172, 4.493392070484582 -22.39801543550165, 4.229074889867841 -23.16979051819184, 4.052863436123348 -23.96361631753032, 3.9647577092511015 -24.933847850055127, 3.788546255506608 \ No newline at end of file diff --git a/MITRotor/Momentum.py b/MITRotor/Momentum.py index 7f1dd1a..7a3c99c 100644 --- a/MITRotor/Momentum.py +++ b/MITRotor/Momentum.py @@ -269,8 +269,8 @@ def __init__(self, def compute_induction(self, Cx: ArrayLike, yaw: float, tilt: float = 0.0) -> ArrayLike: - if tilt != 0: - raise ValueError("Tilt not supported by the Madsen momentum model. Use UMM.") + # if tilt != 0: + # raise ValueError("Tilt not supported by the Madsen momentum model. Use UMM.") if self.cosine_exponent: Ct = Cx / (np.cos(yaw)**2) else: @@ -280,8 +280,8 @@ def compute_induction(self, Cx: ArrayLike, yaw: float, tilt: float = 0.0) -> Arr return an def compute_initial_wake_velocities(self, Ct: float, yaw: float, tilt: float = 0.0) -> ArrayLike: - if tilt != 0: - raise ValueError("Tilt not supported by the Madsen momentum model. Use UMM.") + # if tilt != 0: + # raise ValueError("Tilt not supported by the Madsen momentum model. Use UMM.") u4 = np.sqrt(1 - Ct) v4 = - (1/4) * Ct * np.sin(yaw) w4 = 0.0 diff --git a/examples/example_05_floris_integration.py b/examples/example_05_floris_integration.py index fd8aeb2..8a5b401 100644 --- a/examples/example_05_floris_integration.py +++ b/examples/example_05_floris_integration.py @@ -1,13 +1,18 @@ -import numpy as np import os +import numpy as np +import polars as pl from pathlib import Path + import matplotlib.pyplot as plt from matplotlib import cm from matplotlib.colors import Normalize from matplotlib.cm import ScalarMappable + from floris import FlorisModel, TimeSeries -from MITRotor.FlorisInterface.FlorisInterface import csv_to_interp, default_bem_factory, MITRotorTurbine +from MITRotor.FlorisInterface.FlorisInterface import MITRotorTurbine, default_bem_factory, default_pitch_interp, default_tsr_interp +figdir = Path("fig") +floris_air_density = 1.225 # ------------------ run basic case -------------------------------------------------------- fmodel = FlorisModel("defaults") time_series = TimeSeries( @@ -34,110 +39,137 @@ print("Axial induction factors [-]:\n", fmodel.get_turbine_axial_induction_factors(), "\n") # -------------------- plot pitch and tsr control curves, as well as CT for IEA15MW ------------------ +# Credit to Ilan Upfal for initial validation of MITRotor vs IEA15MW and much of the script below. +# Floris Interface written and tested by Skylar Gering. module_dir = os.path.dirname(__file__) # examples/ -csv_dir = os.path.join(module_dir, "..", "MITRotor", "FlorisInterface") +csv_file = os.path.join(module_dir, "..", "MITRotor", "FlorisInterface", "IEA_15mw_rotor.csv") +df = pl.read_csv(csv_file) -wind_speeds = np.linspace(5, 25.0, 20) +wind_table = df["Wind [m/s]"].to_numpy() +wind_speeds = np.linspace(3, 25, 50) wind_dirs = np.full_like(wind_speeds, 270.0) turbulence_intensity = np.zeros_like(wind_speeds) -# plot pitch and tsr control curves for IEA15MW from figure 2 (https://docs.nrel.gov/docs/fy22osti/82134.pdf) -pitch_csv = os.path.join(csv_dir, "pitch_15mw.csv") -tsr_csv = os.path.join(csv_dir, "tsr_15mw.csv") -pitch_interp = csv_to_interp(pitch_csv) -tsr_interp = csv_to_interp(tsr_csv) +# ------- plot pitch and tsr control curves for IEA15MW from figure 2 (https://docs.nrel.gov/docs/fy22osti/82134.pdf) -------- +pitch_interp = default_pitch_interp() +tsr_interp = default_tsr_interp() +tsrs = [tsr_interp(u) for u in wind_speeds] +pitches = [pitch_interp(u) for u in wind_speeds] # plot interpolated pitch and tsr data fig, ax = plt.subplots(figsize=(8, 6)) ax.scatter( wind_speeds, - pitch_interp(wind_speeds), + pitches, s=40, edgecolors="k", label = "Interpolated Pitch [deg]" ) ax.scatter( wind_speeds, - tsr_interp(wind_speeds), + tsrs, s=40, edgecolors="k", label = "Interpolated Tip-Speed Ratio [-]" ) - # load and plot raw CSV data -tsr_data = np.loadtxt(tsr_csv, delimiter=",", skiprows=1) -pitch_data = np.loadtxt(pitch_csv, delimiter=",", skiprows=1) -tsr_ws, tsr_vals = tsr_data[:, 0], tsr_data[:, 1] -pitch_ws, pitch_vals = pitch_data[:, 0], pitch_data[:, 1] ax.plot( - pitch_ws, - pitch_vals, + wind_table, + df["Pitch [deg]"].to_numpy(), label = "Pitch [deg]" ) ax.plot( - tsr_ws, - tsr_vals, + wind_table, + df["Tip Speed [m/s]"].to_numpy() / wind_table, label = "Tip-Speed Ratio [-]" ) -ax.set_xlabel("Wind Speed [m/s]") -ax.set_title("IEA 15MW: Fixed Bottom Trajectories") -plt.legend() - -# compute CT from floris +ax.set_title("IEA 15MW: Fixed Bottom Trajectories", size = 18) +ax.set_xlabel("Wind Speed [m/s]", size = 16) +ax.tick_params(labelsize=14) +ax.legend(fontsize = 14) +plt.savefig(figdir / "example_5_pitch_tsr_interpolation.png", dpi=300) + +# -------- plot CT and CP values against one another and against IEA15MW from figure 3.1-C (https://docs.nrel.gov/docs/fy20osti/75698.pdf) ------- +# solve Madsen Momentum Model though MITRotor +bem = default_bem_factory() +mit_sols = [bem(pitch=np.deg2rad(pitch_interp(u)), tsr=tsr_interp(u), yaw=0, tilt=0) for u in wind_speeds] +mit_Ct = [sol.Ct() for sol in mit_sols] +mit_Cp = [sol.Cp() for sol in mit_sols] + +# solve FLORIS with MITRotor fmodel = FlorisModel("defaults") - time_series = TimeSeries( wind_speeds=wind_speeds, wind_directions=wind_dirs, turbulence_intensities=turbulence_intensity, ) - fmodel.set(layout_x = [0.0], layout_y = [0.0], wind_data = time_series) fmodel.set_operation_model(MITRotorTurbine()) fmodel.run() floris_Ct = fmodel.get_turbine_thrust_coefficients() +rotor_area = np.pi * bem.rotor.R**2 +floris_power = np.squeeze(fmodel.get_turbine_powers()) +floris_Cp = floris_power / (0.5 * 1.225 * rotor_area * (wind_speeds)**3) +# plot CT values against one another and against IEA15MW from figure 3.1-C (https://docs.nrel.gov/docs/fy20osti/75698.pdf) fig, ax = plt.subplots(figsize=(8, 6)) -cmap = cm.viridis - -# plot setpoint curves for IEA15MW from figure 3.2 (https://docs.nrel.gov/docs/fy20osti/75698.pdf) -setpoint_curves = os.path.join(csv_dir, "pitch_tsr_ct_15mw.csv") -data = np.loadtxt(setpoint_curves, delimiter=",", skiprows=1) -all_cts = np.concatenate([data[:, 2], floris_Ct.flatten()]) -norm = Normalize(vmin=all_cts.min(), vmax=all_cts.max()) - -for ct in np.unique(data[:, 2]): - mask = data[:, 2] == ct - ax.plot( - data[mask, 0], - data[mask, 1], - color=cmap(norm(ct)), - linewidth=2, - label=f"Ct ≈ {ct:.3f}", - ) - -# plot FLORIS points -sc = ax.scatter( - pitch_interp(wind_speeds), - tsr_interp(wind_speeds), - c=floris_Ct, - cmap=cmap, - norm=norm, - s=40, - edgecolors="k", - label = "FLORIS with MITRotor" +ax.plot( + wind_table, + df["Thrust Coefficient [-]"].to_list(), + linewidth=2, + label="IEA15MW $C_T$", + color='tab:orange', + linestyle = "solid" +) + +ax.plot( + wind_speeds, + mit_Ct, + label="MITRotor $C_T$", + linewidth=2, + color='tab:orange', + linestyle = "dashed" +) +ax.plot( + wind_speeds, + floris_Ct, + label="FLORIS $C_T$", + linewidth=2, + color='darkorange', + linestyle = "dotted" +) + +ax.set_xlabel("Wind Speed [m/s]") + + +# plot Cp values against one another and against IEA15MW from figure 3.1-C (https://docs.nrel.gov/docs/fy20osti/75698.pdf) +ax.plot( + wind_table, + df["Aero Power Coefficient [-]"].to_list(), + label="IEA15MW $C_P$", + linewidth=2, + color='tab:blue', + linestyle = "solid" +) +ax.plot( + wind_speeds, + mit_Cp, + label="MITRotor $C_P$", + linewidth=2, + color='tab:blue', + linestyle = "dashed" +) +ax.plot( + wind_speeds, + floris_Cp, + label="FLORIS $C_P$", + linewidth=2, + color='tab:blue', + linestyle = "dotted" ) +ax.set_title("IEA 15 MW FLORIS Interface Validation", size = 18) +ax.set_xlabel("Wind Speed [m/s]", size = 16) +ax.tick_params(labelsize=14) +ax.legend(fontsize = 14) +plt.savefig(figdir / "example_5_IEA15mw_CT_CP.png", dpi=300) -# colorbar that covers all Ct values -sm = ScalarMappable(norm=norm, cmap=cmap) -sm.set_array([]) -plt.colorbar(sm, ax=ax, label="$C_T$") - -# label plot -ax.set_xlabel("Pitch [deg]") -ax.set_ylabel("Tip-Speed Ratio [-]") -ax.set_title("IEA 15MW: $C_T$ Control Curves vs FLORIS/MITRotor") -ax.grid(True, alpha=0.3) -ax.legend(fontsize=9) -plt.tight_layout() -plt.show() diff --git a/tests/test_floris_interface.py b/tests/test_floris_interface.py index 46f0fe8..ad109ad 100644 --- a/tests/test_floris_interface.py +++ b/tests/test_floris_interface.py @@ -1,34 +1,29 @@ +import os import numpy as np import pytest -import os +import polars as pl from numpy.testing import assert_almost_equal, assert_allclose from floris import FlorisModel, TimeSeries -from MITRotor.FlorisInterface import FlorisInterface -from MITRotor.FlorisInterface.FlorisInterface import default_bem_factory, default_pitch_csv, default_tsr_csv -from MITRotor.FlorisInterface.FlorisInterface import MITRotorTurbine, csv_to_interp +from MITRotor.FlorisInterface.FlorisInterface import MITRotorTurbine, default_bem_factory, default_pitch_interp, default_tsr_interp def test_pitch_tsr_interpolation(): - # get 15MW CSV file paths - module_dir = os.path.dirname(__file__) # tests/ - pitch_csv = os.path.join(module_dir, "..", "MITRotor", "FlorisInterface", "pitch_15mw.csv") - tsr_csv = os.path.join(module_dir, "..", "MITRotor", "FlorisInterface", "tsr_15mw.csv") - pitch_csv = os.path.abspath(pitch_csv) - tsr_csv = os.path.abspath(tsr_csv) - - # create interpolators - tsr_interp = csv_to_interp(tsr_csv) - pitch_interp = csv_to_interp(pitch_csv) + # create default interpolators + tsr_interp = default_tsr_interp() + pitch_interp = default_pitch_interp() # load raw CSV data - tsr_data = np.loadtxt(tsr_csv, delimiter=",", skiprows=1) - pitch_data = np.loadtxt(pitch_csv, delimiter=",", skiprows=1) - tsr_ws, tsr_vals = tsr_data[:, 0], tsr_data[:, 1] - pitch_ws, pitch_vals = pitch_data[:, 0], pitch_data[:, 1] + module_dir = os.path.dirname(__file__) # tests/ + validation_csv = os.path.abspath(os.path.join(module_dir, "..", "MITRotor", "FlorisInterface", "IEA_15mw_rotor.csv")) + df = pl.read_csv(validation_csv) + wind_data = df["Wind [m/s]"].to_numpy() + pitch_data = df["Pitch [deg]"].to_numpy() + tip_speed_data = df["Tip Speed [m/s]"].to_numpy() + tsr_data = tip_speed_data / wind_data # interpolator reproduces raw data - assert_allclose(tsr_interp(tsr_ws), tsr_vals, rtol=1e-12, atol=1e-12) - assert_allclose(pitch_interp(pitch_ws), pitch_vals, rtol=1e-12, atol=1e-12) + assert_allclose(tsr_interp(wind_data), tsr_data, rtol=1e-12, atol=1e-12) + assert_allclose(pitch_interp(wind_data), pitch_data, rtol=1e-12, atol=1e-12) # reasonable values x_interp_vals = np.linspace(0.0, 25.0, 100) @@ -44,8 +39,8 @@ def test_pitch_tsr_interpolation(): # compute MITRotor BEM outputs directly def compute_mitrotor_cp_ct_a(wind_speeds, yaw_deg = 0.0, tilt_deg = 0.0): bem_model = default_bem_factory() # default BEM (IEA15MW) used in floris interface - pitch_interp = csv_to_interp(default_pitch_csv()) # IEA15MW pitch curve - tsr_interp = csv_to_interp(default_tsr_csv()) # IEA15MW tsr curve + pitch_interp = default_pitch_interp() # IEA15MW pitch curve + tsr_interp = default_tsr_interp() # IEA15MW tsr curve n = len(wind_speeds) Ct = np.empty(n) From a5798d4a7574d6d4c684c28e50d94137e82704b1 Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Wed, 21 Jan 2026 13:59:17 -0500 Subject: [PATCH 13/19] Switch default to UMM Rotor-averaged and add more rotors to example for testing --- MITRotor/FlorisInterface/FlorisInterface.py | 7 +- examples/example_05_floris_integration.py | 325 ++++++++++++++++---- 2 files changed, 276 insertions(+), 56 deletions(-) diff --git a/MITRotor/FlorisInterface/FlorisInterface.py b/MITRotor/FlorisInterface/FlorisInterface.py index 0d96c5e..f496c69 100644 --- a/MITRotor/FlorisInterface/FlorisInterface.py +++ b/MITRotor/FlorisInterface/FlorisInterface.py @@ -7,20 +7,19 @@ # FLORIS Imports from floris.type_dec import floris_float_type, NDArrayFloat from floris.core.turbine.operation_models import BaseOperationModel -from floris.core.rotor_velocity import average_velocity, rotor_velocity_air_density_correction +from floris.core.rotor_velocity import average_velocity # MITRotor / UMM Imports from MITRotor.ReferenceTurbines import IEA15MW -from MITRotor.Momentum import MadsenMomentum +from MITRotor.Momentum import UnifiedMomentum from MITRotor.Geometry import BEMGeometry from MITRotor.TipLoss import NoTipLoss from MITRotor.BEMSolver import BEM -from UnifiedMomentumModel.Utilities.Geometry import calc_eff_yaw # default rotor if none provided by user (IEA 15MW) def default_bem_factory(): return BEM( rotor=IEA15MW(), - momentum_model=MadsenMomentum(averaging="annulus"), + momentum_model=UnifiedMomentum(averaging="rotor"), geometry=BEMGeometry(Nr=10, Ntheta=20), tiploss_model=NoTipLoss() ) diff --git a/examples/example_05_floris_integration.py b/examples/example_05_floris_integration.py index 8a5b401..f4baae4 100644 --- a/examples/example_05_floris_integration.py +++ b/examples/example_05_floris_integration.py @@ -2,14 +2,27 @@ import numpy as np import polars as pl from pathlib import Path +import time +import warnings + +warnings.filterwarnings("ignore", category=RuntimeWarning) # JUST FOR NOW + import matplotlib.pyplot as plt from matplotlib import cm from matplotlib.colors import Normalize from matplotlib.cm import ScalarMappable +# Floris imports from floris import FlorisModel, TimeSeries + +# MITRotor / UMM Imports from MITRotor.FlorisInterface.FlorisInterface import MITRotorTurbine, default_bem_factory, default_pitch_interp, default_tsr_interp +from MITRotor.ReferenceTurbines import IEA15MW +from MITRotor.Momentum import UnifiedMomentum, MadsenMomentum +from MITRotor.Geometry import BEMGeometry +from MITRotor.TipLoss import NoTipLoss +from MITRotor.BEMSolver import BEM figdir = Path("fig") floris_air_density = 1.225 @@ -90,86 +103,294 @@ plt.savefig(figdir / "example_5_pitch_tsr_interpolation.png", dpi=300) # -------- plot CT and CP values against one another and against IEA15MW from figure 3.1-C (https://docs.nrel.gov/docs/fy20osti/75698.pdf) ------- -# solve Madsen Momentum Model though MITRotor -bem = default_bem_factory() -mit_sols = [bem(pitch=np.deg2rad(pitch_interp(u)), tsr=tsr_interp(u), yaw=0, tilt=0) for u in wind_speeds] -mit_Ct = [sol.Ct() for sol in mit_sols] -mit_Cp = [sol.Cp() for sol in mit_sols] +# solve UMM-BEM though MITRotor - rotor averaged +bem_rotor_umm = default_bem_factory() +mit_rotor_umm_start = time.time() +mit_sols_rotor_umm = [bem_rotor_umm(pitch=np.deg2rad(pitch_interp(u)), tsr=tsr_interp(u), yaw=0, tilt=0) for u in wind_speeds] +mit_rotor_umm_end = time.time() +mit_Ct_rotor_umm = [sol.Ct() for sol in mit_sols_rotor_umm] +mit_Cp_rotor_umm = [sol.Cp() for sol in mit_sols_rotor_umm] +print("MITRotor UMM-BEM Rotor-Averaged: " + str(mit_rotor_umm_end - mit_rotor_umm_start) + " seconds") -# solve FLORIS with MITRotor -fmodel = FlorisModel("defaults") +# solve UMM-BEM though MITRotor - annulus averaged +bem_annulus_umm = BEM( + rotor=IEA15MW(), + momentum_model=UnifiedMomentum(averaging="annulus"), + geometry=BEMGeometry(Nr=10, Ntheta=20), + tiploss_model=NoTipLoss(), + ) +mit_annulus_umm_start = time.time() +mit_sols_annulus_umm = [bem_annulus_umm(pitch=np.deg2rad(pitch_interp(u)), tsr=tsr_interp(u), yaw=0, tilt=0) for u in wind_speeds] +mit_annulus_umm_end = time.time() +mit_Ct_annulus_umm = [sol.Ct() for sol in mit_sols_annulus_umm] +mit_Cp_annulus_umm = [sol.Cp() for sol in mit_sols_annulus_umm] +print("MITRotor UMM-BEM Annulus-Averaged: " + str(mit_annulus_umm_end - mit_annulus_umm_start) + " seconds") + +# solve Madsen-BEM though MITRotor - rotor averaged +bem_rotor_madesen = BEM( + rotor=IEA15MW(), + momentum_model=MadsenMomentum(averaging="rotor"), + geometry=BEMGeometry(Nr=10, Ntheta=20), + tiploss_model=NoTipLoss() + ) +mit_rotor_madsen_start = time.time() +mit_sols_rotor_madsen = [bem_rotor_madesen(pitch=np.deg2rad(pitch_interp(u)), tsr=tsr_interp(u), yaw=0, tilt=0) for u in wind_speeds] +mit_rotor_madsen_end = time.time() +mit_Ct_rotor_madsen = [sol.Ct() for sol in mit_sols_rotor_madsen] +mit_Cp_rotor_madsen = [sol.Cp() for sol in mit_sols_rotor_madsen] +print("MITRotor Madsen-BEM Rotor-Averaged: " + str(mit_rotor_madsen_end - mit_rotor_madsen_start) + " seconds") + +# solve Madsen-BEM though MITRotor - annulus averaged +bem_annulus_madesen = BEM( + rotor=IEA15MW(), + momentum_model=MadsenMomentum(averaging="annulus"), + geometry=BEMGeometry(Nr=10, Ntheta=20), + tiploss_model=NoTipLoss() + ) +mit_annulus_madsen_start = time.time() +mit_sols_annulus_madsen = [bem_annulus_madesen(pitch=np.deg2rad(pitch_interp(u)), tsr=tsr_interp(u), yaw=0, tilt=0) for u in wind_speeds] +mit_annulus_madsen_end = time.time() +mit_Ct_annulus_madsen = [sol.Ct() for sol in mit_sols_annulus_madsen] +mit_Cp_annulus_madsen = [sol.Cp() for sol in mit_sols_annulus_madsen] +print("MITRotor Madsen-BEM Annulus-Averaged: " + str(mit_annulus_madsen_end - mit_annulus_madsen_start) + " seconds") + +# solve FLORIS with UMM-BEM though MITRotor - rotor averaged time_series = TimeSeries( wind_speeds=wind_speeds, wind_directions=wind_dirs, turbulence_intensities=turbulence_intensity, ) -fmodel.set(layout_x = [0.0], layout_y = [0.0], wind_data = time_series) -fmodel.set_operation_model(MITRotorTurbine()) -fmodel.run() -floris_Ct = fmodel.get_turbine_thrust_coefficients() -rotor_area = np.pi * bem.rotor.R**2 -floris_power = np.squeeze(fmodel.get_turbine_powers()) -floris_Cp = floris_power / (0.5 * 1.225 * rotor_area * (wind_speeds)**3) +fmodel_rotor_umm = FlorisModel("defaults") +fmodel_rotor_umm.set(layout_x = [0.0], layout_y = [0.0], wind_data = time_series) +fmodel_rotor_umm.set_operation_model(MITRotorTurbine()) # default bem_model uses rotor-averaging +floris_rotor_umm_start = time.time() +fmodel_rotor_umm.run() +floris_rotor_umm_end = time.time() +floris_Ct_rotor_umm = fmodel_rotor_umm.get_turbine_thrust_coefficients() +rotor_area = np.pi * bem_rotor_umm.rotor.R**2 +floris_power_rotor_umm = np.squeeze(fmodel_rotor_umm.get_turbine_powers()) +floris_Cp_rotor_umm = floris_power_rotor_umm / (0.5 * 1.225 * rotor_area * (wind_speeds)**3) +print("FLORIS UMM-BEM Rotor-Averaged: " + str(floris_rotor_umm_end - floris_rotor_umm_start) + " seconds") + +# solve FLORIS with UMM-BEM though MITRotor - annulus averaged +fmodel_annulus_umm = FlorisModel("defaults") +fmodel_annulus_umm.set(layout_x = [0.0], layout_y = [0.0], wind_data = time_series) +fmodel_annulus_umm.set_operation_model(MITRotorTurbine(bem_model = bem_annulus_umm)) # default bem_model uses rotor-averaging +floris_annulus_umm_start = time.time() +fmodel_annulus_umm.run() +floris_annulus_umm_end = time.time() +floris_Ct_annulus_umm = fmodel_annulus_umm.get_turbine_thrust_coefficients() +floris_power_annulus_umm = np.squeeze(fmodel_annulus_umm.get_turbine_powers()) +floris_Cp_annulus_umm = floris_power_annulus_umm / (0.5 * 1.225 * rotor_area * (wind_speeds)**3) +print("FLORIS UMM-BEM Annulus-Averaged: " + str(floris_annulus_umm_end - floris_annulus_umm_start) + " seconds") + +# solve FLORIS with Madsen-BEM though MITRotor - rotor averaged +fmodel_rotor_madsen = FlorisModel("defaults") +fmodel_rotor_madsen.set(layout_x = [0.0], layout_y = [0.0], wind_data = time_series) +fmodel_rotor_madsen.set_operation_model(MITRotorTurbine(bem_model = bem_rotor_madesen)) # default bem_model uses rotor-averaging +floris_rotor_madsen_start = time.time() +fmodel_rotor_madsen.run() +floris_rotor_madsen_end = time.time() +floris_Ct_rotor_madsen = fmodel_rotor_madsen.get_turbine_thrust_coefficients() +floris_power_rotor_madsen = np.squeeze(fmodel_rotor_madsen.get_turbine_powers()) +floris_Cp_rotor_madsen = floris_power_rotor_madsen / (0.5 * 1.225 * rotor_area * (wind_speeds)**3) +print("FLORIS Madsen-BEM Rotor-Averaged: " + str(floris_rotor_madsen_end - floris_rotor_madsen_start) + " seconds") + +# solve FLORIS with Madsen-BEM though MITRotor - annulus averaged +fmodel_annulus_madsen = FlorisModel("defaults") +fmodel_annulus_madsen.set(layout_x = [0.0], layout_y = [0.0], wind_data = time_series) +fmodel_annulus_madsen.set_operation_model(MITRotorTurbine(bem_model = bem_annulus_madesen)) # default bem_model uses rotor-averaging +floris_annulus_madsen_start = time.time() +fmodel_annulus_madsen.run() +floris_annulus_madsen_end = time.time() +floris_Ct_annulus_madsen = fmodel_annulus_madsen.get_turbine_thrust_coefficients() +floris_power_annulus_madsen = np.squeeze(fmodel_annulus_madsen.get_turbine_powers()) +floris_Cp_annulus_madsen = floris_power_annulus_madsen / (0.5 * 1.225 * rotor_area * (wind_speeds)**3) +print("FLORIS Madsen-BEM Annulus-Averaged: " + str(floris_annulus_madsen_end - floris_annulus_madsen_start) + " seconds") # plot CT values against one another and against IEA15MW from figure 3.1-C (https://docs.nrel.gov/docs/fy20osti/75698.pdf) -fig, ax = plt.subplots(figsize=(8, 6)) -ax.plot( +fig, (ax0, ax1) = plt.subplots(figsize=(16, 8), ncols = 2, sharex = True, sharey = True) +fig.suptitle("IEA 15 MW FLORIS Interface Validation", size = 18) +alpha = 0.8 +ax0.plot( wind_table, df["Thrust Coefficient [-]"].to_list(), - linewidth=2, - label="IEA15MW $C_T$", + linewidth=4, + label="IEA15MW", color='tab:orange', - linestyle = "solid" + linestyle = "solid", + alpha = alpha, ) -ax.plot( +ax0.plot( wind_speeds, - mit_Ct, - label="MITRotor $C_T$", - linewidth=2, - color='tab:orange', - linestyle = "dashed" + mit_Ct_rotor_umm, + label="MITRotor UMM Rotor-Averaged", + linewidth=4, + color='tab:blue', + linestyle = "solid", + alpha = alpha, ) -ax.plot( +ax0.plot( wind_speeds, - floris_Ct, - label="FLORIS $C_T$", - linewidth=2, - color='darkorange', - linestyle = "dotted" + mit_Ct_annulus_umm, + label="MITRotor UMM Annulus-Averaged", + linewidth=4, + color='tab:green', + linestyle = "solid", + alpha = alpha, +) +# ax0.plot( +# wind_speeds, +# mit_Ct_rotor_madsen, +# label="MITRotor Madsen Rotor-Averaged", +# linewidth=4, +# color='tab:purple', +# linestyle = "solid", +# alpha = alpha, +# ) +# ax0.plot( +# wind_speeds, +# mit_Ct_annulus_madsen, +# label="MITRotor Madsen Annulus-Averaged", +# linewidth=4, +# color='tab:red', +# linestyle = "solid", +# alpha = alpha, +# ) +ax0.plot( + wind_speeds, + floris_Ct_rotor_umm, + label="FLORIS-MITRotor UMM Rotor-Averaged", + linewidth=4, + color='tab:blue', + linestyle = "dashed", + alpha = alpha, +) +ax0.plot( + wind_speeds, + floris_Ct_annulus_umm, + label="FLORIS-MITRotor UMM Annulus-Averaged", + linewidth=4, + color='tab:green', + linestyle = "dashed", + alpha = alpha, ) -ax.set_xlabel("Wind Speed [m/s]") +ax0.plot( + wind_speeds, + floris_Ct_rotor_madsen, + label="FLORIS-MITRotor Madsen Rotor-Averaged", + linewidth=4, + color='tab:purple', + linestyle = "dashed", + alpha = alpha, +) +ax0.plot( + wind_speeds, + floris_Ct_annulus_madsen, + label="FLORIS-MITRotor Madsen Annulus-Averaged", + linewidth=4, + color='tab:red', + linestyle = "dashed", + alpha = alpha, +) +ax0.set_xlabel("Wind Speed [m/s]", size = 16) +ax0.set_ylabel("$C_T$", size = 16) +ax0.tick_params(labelsize = 14) +ax0.set_title("$C_T$", size = 18) # plot Cp values against one another and against IEA15MW from figure 3.1-C (https://docs.nrel.gov/docs/fy20osti/75698.pdf) -ax.plot( +ax1.plot( wind_table, df["Aero Power Coefficient [-]"].to_list(), - label="IEA15MW $C_P$", - linewidth=2, - color='tab:blue', - linestyle = "solid" + label="IEA15MW", + linewidth=4, + color='tab:orange', + linestyle = "solid", + alpha = alpha, ) -ax.plot( +ax1.plot( wind_speeds, - mit_Cp, - label="MITRotor $C_P$", - linewidth=2, + mit_Cp_rotor_umm, + label="MITRotor UMM Rotor-Averaged", + linewidth=4, color='tab:blue', - linestyle = "dashed" + linestyle = "solid", + alpha = alpha, ) -ax.plot( +ax1.plot( + wind_speeds, + mit_Cp_annulus_umm, + label="MITRotor UMM Annulus-Averaged", + linewidth=4, + color='tab:green', + linestyle = "solid", + alpha = alpha, +) +# ax1.plot( +# wind_speeds, +# mit_Cp_rotor_madsen, +# label="MITRotor Madsen Rotor-Averaged", +# linewidth=4, +# color='tab:purple', +# linestyle = "solid", +# alpha = alpha, +# ) +# ax1.plot( +# wind_speeds, +# mit_Cp_annulus_madsen, +# label="MITRotor Madsen Annulus-Averaged", +# linewidth=4, +# color='tab:red', +# linestyle = "solid", +# alpha = alpha, +# ) +ax1.plot( wind_speeds, - floris_Cp, - label="FLORIS $C_P$", - linewidth=2, + floris_Cp_rotor_umm, + label="FLORIS-MITRotor UMM Rotor-Averaged", + linewidth=4, color='tab:blue', - linestyle = "dotted" + linestyle = "dashed", + alpha = alpha, +) +ax1.plot( + wind_speeds, + floris_Cp_annulus_umm, + label="FLORIS-MITRotor UMM Annulus-Averaged", + linewidth=4, + color='tab:green', + linestyle = "dashed", + alpha = alpha, +) +ax1.plot( + wind_speeds, + floris_Cp_rotor_madsen, + label="FLORIS-MITRotor Madsen Rotor-Averaged", + linewidth=4, + color='tab:purple', + linestyle = "dashed", + alpha = alpha, +) +ax1.plot( + wind_speeds, + floris_Cp_annulus_madsen, + label="FLORIS-MITRotor Madsen Annulus-Averaged", + linewidth=4, + color='tab:red', + linestyle = "dashed", + alpha = alpha, ) -ax.set_title("IEA 15 MW FLORIS Interface Validation", size = 18) -ax.set_xlabel("Wind Speed [m/s]", size = 16) -ax.tick_params(labelsize=14) -ax.legend(fontsize = 14) -plt.savefig(figdir / "example_5_IEA15mw_CT_CP.png", dpi=300) +ax1.set_xlabel("Wind Speed [m/s]", size = 16) +ax1.set_ylabel("$C_P$", size = 16) +ax1.tick_params(labelsize = 14) +ax1.set_title("$C_P$", size = 18) +ax1.legend( + fontsize=14, + loc="upper right", +) + +plt.savefig(figdir / "example_5_IEA15mw_CT_CP.png", dpi=300) From daa0d95cdf177a3c70f57a8a8d008f99119b96c9 Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Sat, 28 Feb 2026 13:01:20 -0500 Subject: [PATCH 14/19] Remove interpolation of setpoints from timing --- examples/example_05_floris_integration.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/example_05_floris_integration.py b/examples/example_05_floris_integration.py index f4baae4..e26e5e8 100644 --- a/examples/example_05_floris_integration.py +++ b/examples/example_05_floris_integration.py @@ -59,7 +59,7 @@ df = pl.read_csv(csv_file) wind_table = df["Wind [m/s]"].to_numpy() -wind_speeds = np.linspace(3, 25, 50) +wind_speeds = np.linspace(5, 25, 20) wind_dirs = np.full_like(wind_speeds, 270.0) turbulence_intensity = np.zeros_like(wind_speeds) @@ -104,9 +104,10 @@ # -------- plot CT and CP values against one another and against IEA15MW from figure 3.1-C (https://docs.nrel.gov/docs/fy20osti/75698.pdf) ------- # solve UMM-BEM though MITRotor - rotor averaged +pitches_rad = np.deg2rad(pitches) bem_rotor_umm = default_bem_factory() mit_rotor_umm_start = time.time() -mit_sols_rotor_umm = [bem_rotor_umm(pitch=np.deg2rad(pitch_interp(u)), tsr=tsr_interp(u), yaw=0, tilt=0) for u in wind_speeds] +mit_sols_rotor_umm = [bem_rotor_umm(pitch=pitches_rad[i], tsr=tsrs[i], yaw=0, tilt=0) for i in range(len(tsrs))] mit_rotor_umm_end = time.time() mit_Ct_rotor_umm = [sol.Ct() for sol in mit_sols_rotor_umm] mit_Cp_rotor_umm = [sol.Cp() for sol in mit_sols_rotor_umm] @@ -120,7 +121,7 @@ tiploss_model=NoTipLoss(), ) mit_annulus_umm_start = time.time() -mit_sols_annulus_umm = [bem_annulus_umm(pitch=np.deg2rad(pitch_interp(u)), tsr=tsr_interp(u), yaw=0, tilt=0) for u in wind_speeds] +mit_sols_annulus_umm = [bem_annulus_umm(pitch=pitches_rad[i], tsr=tsrs[i], yaw=0, tilt=0) for i in range(len(tsrs))] mit_annulus_umm_end = time.time() mit_Ct_annulus_umm = [sol.Ct() for sol in mit_sols_annulus_umm] mit_Cp_annulus_umm = [sol.Cp() for sol in mit_sols_annulus_umm] From a5856409dacdb6eac03c2d2dfef8ed9eb08756c1 Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Sun, 1 Mar 2026 12:18:30 -0500 Subject: [PATCH 15/19] Updated example 6 for non-vectorized code --- ...on.py => example_06_floris_integration.py} | 276 ++++++++---------- examples/example_timing.py | 12 + 2 files changed, 140 insertions(+), 148 deletions(-) rename examples/{example_05_floris_integration.py => example_06_floris_integration.py} (58%) create mode 100644 examples/example_timing.py diff --git a/examples/example_05_floris_integration.py b/examples/example_06_floris_integration.py similarity index 58% rename from examples/example_05_floris_integration.py rename to examples/example_06_floris_integration.py index e26e5e8..455c23d 100644 --- a/examples/example_05_floris_integration.py +++ b/examples/example_06_floris_integration.py @@ -19,7 +19,7 @@ # MITRotor / UMM Imports from MITRotor.FlorisInterface.FlorisInterface import MITRotorTurbine, default_bem_factory, default_pitch_interp, default_tsr_interp from MITRotor.ReferenceTurbines import IEA15MW -from MITRotor.Momentum import UnifiedMomentum, MadsenMomentum +from MITRotor.Momentum import UnifiedMomentum, UnifiedMomentumLUT from MITRotor.Geometry import BEMGeometry from MITRotor.TipLoss import NoTipLoss from MITRotor.BEMSolver import BEM @@ -100,14 +100,17 @@ ax.set_xlabel("Wind Speed [m/s]", size = 16) ax.tick_params(labelsize=14) ax.legend(fontsize = 14) -plt.savefig(figdir / "example_5_pitch_tsr_interpolation.png", dpi=300) +plt.savefig(figdir / "example_6_pitch_tsr_interpolation.png", dpi=300) # -------- plot CT and CP values against one another and against IEA15MW from figure 3.1-C (https://docs.nrel.gov/docs/fy20osti/75698.pdf) ------- # solve UMM-BEM though MITRotor - rotor averaged pitches_rad = np.deg2rad(pitches) bem_rotor_umm = default_bem_factory() mit_rotor_umm_start = time.time() -mit_sols_rotor_umm = [bem_rotor_umm(pitch=pitches_rad[i], tsr=tsrs[i], yaw=0, tilt=0) for i in range(len(tsrs))] +pitches = np.deg2rad(pitch_interp(wind_speeds)) +tsrs = tsr_interp(wind_speeds) +yaws, tilts = np.zeros_like(pitches), np.zeros_like(pitches) +mit_sols_rotor_umm = [bem_rotor_umm(pitch=pitches[i], tsr=tsrs[i], yaw=yaws[i], tilt=tilts[i]) for i in range(len(pitches))] mit_rotor_umm_end = time.time() mit_Ct_rotor_umm = [sol.Ct() for sol in mit_sols_rotor_umm] mit_Cp_rotor_umm = [sol.Cp() for sol in mit_sols_rotor_umm] @@ -121,39 +124,40 @@ tiploss_model=NoTipLoss(), ) mit_annulus_umm_start = time.time() -mit_sols_annulus_umm = [bem_annulus_umm(pitch=pitches_rad[i], tsr=tsrs[i], yaw=0, tilt=0) for i in range(len(tsrs))] +mit_sols_annulus_umm = [bem_annulus_umm(pitch=pitches[i], tsr=tsrs[i], yaw=yaws[i], tilt=tilts[i]) for i in range(len(pitches))] mit_annulus_umm_end = time.time() mit_Ct_annulus_umm = [sol.Ct() for sol in mit_sols_annulus_umm] mit_Cp_annulus_umm = [sol.Cp() for sol in mit_sols_annulus_umm] print("MITRotor UMM-BEM Annulus-Averaged: " + str(mit_annulus_umm_end - mit_annulus_umm_start) + " seconds") -# solve Madsen-BEM though MITRotor - rotor averaged -bem_rotor_madesen = BEM( - rotor=IEA15MW(), - momentum_model=MadsenMomentum(averaging="rotor"), - geometry=BEMGeometry(Nr=10, Ntheta=20), - tiploss_model=NoTipLoss() - ) -mit_rotor_madsen_start = time.time() -mit_sols_rotor_madsen = [bem_rotor_madesen(pitch=np.deg2rad(pitch_interp(u)), tsr=tsr_interp(u), yaw=0, tilt=0) for u in wind_speeds] -mit_rotor_madsen_end = time.time() -mit_Ct_rotor_madsen = [sol.Ct() for sol in mit_sols_rotor_madsen] -mit_Cp_rotor_madsen = [sol.Cp() for sol in mit_sols_rotor_madsen] -print("MITRotor Madsen-BEM Rotor-Averaged: " + str(mit_rotor_madsen_end - mit_rotor_madsen_start) + " seconds") +# solve UMM-BEM though MITRotor - sector averaged +# bem_sector_umm = BEM( +# rotor=IEA15MW(), +# momentum_model=UnifiedMomentum(averaging="sector"), +# geometry=BEMGeometry(Nr=10, Ntheta=20), +# tiploss_model=NoTipLoss(), +# ) +# mit_sector_umm_start = time.time() +# mit_sols_sector_umm = bem_sector_umm(pitch=pitches, tsr=tsrs, yaw=yaws, tilt=tilts) +# mit_sector_umm_end = time.time() +# mit_Ct_sector_umm = mit_sols_sector_umm.Ct() +# mit_Cp_sector_umm = mit_sols_sector_umm.Cp() +# print("MITRotor UMM-BEM Sector-Averaged: " + str(mit_sector_umm_end - mit_sector_umm_start) + " seconds") -# solve Madsen-BEM though MITRotor - annulus averaged -bem_annulus_madesen = BEM( - rotor=IEA15MW(), - momentum_model=MadsenMomentum(averaging="annulus"), - geometry=BEMGeometry(Nr=10, Ntheta=20), - tiploss_model=NoTipLoss() - ) -mit_annulus_madsen_start = time.time() -mit_sols_annulus_madsen = [bem_annulus_madesen(pitch=np.deg2rad(pitch_interp(u)), tsr=tsr_interp(u), yaw=0, tilt=0) for u in wind_speeds] -mit_annulus_madsen_end = time.time() -mit_Ct_annulus_madsen = [sol.Ct() for sol in mit_sols_annulus_madsen] -mit_Cp_annulus_madsen = [sol.Cp() for sol in mit_sols_annulus_madsen] -print("MITRotor Madsen-BEM Annulus-Averaged: " + str(mit_annulus_madsen_end - mit_annulus_madsen_start) + " seconds") +# solve UMM-BEM with LUT though MITRotor - annulus averaged +print("Making LUT!") +bem_annulus_umm_LUT = BEM( + rotor=IEA15MW(), + momentum_model=UnifiedMomentumLUT(averaging="annulus", cache_fn = Path("cache")/ "lut.csv"), + geometry=BEMGeometry(Nr=10, Ntheta=20), + tiploss_model=NoTipLoss(), +) +mit_annulus_umm_LUT_start = time.time() +mit_sols_annulus_umm_LUT = [bem_annulus_umm_LUT(pitch=pitches[i], tsr=tsrs[i], yaw=yaws[i], tilt=tilts[i]) for i in range(len(pitches))] +mit_annulus_umm_LUT_end = time.time() +mit_Ct_annulus_umm_LUT = [sol.Ct() for sol in mit_sols_annulus_umm_LUT] +mit_Cp_annulus_umm_LUT = [sol.Cp() for sol in mit_sols_annulus_umm_LUT] +print("MITRotor UMM-BEM LUT Annulus-Averaged: " + str(mit_annulus_umm_LUT_end - mit_annulus_umm_LUT_start) + " seconds") # solve FLORIS with UMM-BEM though MITRotor - rotor averaged time_series = TimeSeries( @@ -185,213 +189,189 @@ floris_Cp_annulus_umm = floris_power_annulus_umm / (0.5 * 1.225 * rotor_area * (wind_speeds)**3) print("FLORIS UMM-BEM Annulus-Averaged: " + str(floris_annulus_umm_end - floris_annulus_umm_start) + " seconds") -# solve FLORIS with Madsen-BEM though MITRotor - rotor averaged -fmodel_rotor_madsen = FlorisModel("defaults") -fmodel_rotor_madsen.set(layout_x = [0.0], layout_y = [0.0], wind_data = time_series) -fmodel_rotor_madsen.set_operation_model(MITRotorTurbine(bem_model = bem_rotor_madesen)) # default bem_model uses rotor-averaging -floris_rotor_madsen_start = time.time() -fmodel_rotor_madsen.run() -floris_rotor_madsen_end = time.time() -floris_Ct_rotor_madsen = fmodel_rotor_madsen.get_turbine_thrust_coefficients() -floris_power_rotor_madsen = np.squeeze(fmodel_rotor_madsen.get_turbine_powers()) -floris_Cp_rotor_madsen = floris_power_rotor_madsen / (0.5 * 1.225 * rotor_area * (wind_speeds)**3) -print("FLORIS Madsen-BEM Rotor-Averaged: " + str(floris_rotor_madsen_end - floris_rotor_madsen_start) + " seconds") +# solve FLORIS with UMM-BEM with LUT though MITRotor - annulus averaged +fmodel_annulus_umm_LUT = FlorisModel("defaults") +fmodel_annulus_umm_LUT.set(layout_x = [0.0], layout_y = [0.0], wind_data = time_series) +fmodel_annulus_umm_LUT.set_operation_model(MITRotorTurbine(bem_model = bem_annulus_umm_LUT)) # default bem_model uses rotor-averaging +floris_annulus_umm_LUT_start = time.time() +fmodel_annulus_umm_LUT.run() +floris_annulus_umm_LUT_end = time.time() +floris_Ct_annulus_umm_LUT = fmodel_annulus_umm_LUT.get_turbine_thrust_coefficients() +floris_power_annulus_umm_LUT = np.squeeze(fmodel_annulus_umm_LUT.get_turbine_powers()) +floris_Cp_annulus_umm_LUT = floris_power_annulus_umm_LUT / (0.5 * 1.225 * rotor_area * (wind_speeds)**3) +print("FLORIS UMM-BEM LUT Annulus-Averaged: " + str(floris_annulus_umm_LUT_end - floris_annulus_umm_LUT_start) + " seconds") -# solve FLORIS with Madsen-BEM though MITRotor - annulus averaged -fmodel_annulus_madsen = FlorisModel("defaults") -fmodel_annulus_madsen.set(layout_x = [0.0], layout_y = [0.0], wind_data = time_series) -fmodel_annulus_madsen.set_operation_model(MITRotorTurbine(bem_model = bem_annulus_madesen)) # default bem_model uses rotor-averaging -floris_annulus_madsen_start = time.time() -fmodel_annulus_madsen.run() -floris_annulus_madsen_end = time.time() -floris_Ct_annulus_madsen = fmodel_annulus_madsen.get_turbine_thrust_coefficients() -floris_power_annulus_madsen = np.squeeze(fmodel_annulus_madsen.get_turbine_powers()) -floris_Cp_annulus_madsen = floris_power_annulus_madsen / (0.5 * 1.225 * rotor_area * (wind_speeds)**3) -print("FLORIS Madsen-BEM Annulus-Averaged: " + str(floris_annulus_madsen_end - floris_annulus_madsen_start) + " seconds") +# Presentation-friendly typography +plt.rcParams.update({ + "font.size": 20, + "axes.titlesize": 20, + "axes.labelsize": 22, + "xtick.labelsize": 20, + "ytick.labelsize": 20, +}) # plot CT values against one another and against IEA15MW from figure 3.1-C (https://docs.nrel.gov/docs/fy20osti/75698.pdf) -fig, (ax0, ax1) = plt.subplots(figsize=(16, 8), ncols = 2, sharex = True, sharey = True) -fig.suptitle("IEA 15 MW FLORIS Interface Validation", size = 18) -alpha = 0.8 +fig, (ax0, ax1) = plt.subplots(figsize=(17, 9), ncols = 2, sharex = True, sharey = True) +fig.suptitle("IEA 15 MW FLORIS Interface Validation") +alpha = 0.6 ax0.plot( wind_table, df["Thrust Coefficient [-]"].to_list(), - linewidth=4, + linewidth=6, label="IEA15MW", color='tab:orange', linestyle = "solid", alpha = alpha, + zorder = 1, ) ax0.plot( wind_speeds, mit_Ct_rotor_umm, label="MITRotor UMM Rotor-Averaged", - linewidth=4, + linewidth=6, color='tab:blue', linestyle = "solid", alpha = alpha, + zorder = 1, ) +ax0.plot( + wind_speeds, + mit_Ct_annulus_umm_LUT, + label="MITRotor UMM LUT Annulus-Averaged", + linewidth=6, + color='tab:red', + linestyle = "solid", + alpha = alpha, + zorder = 1, +) + ax0.plot( wind_speeds, mit_Ct_annulus_umm, label="MITRotor UMM Annulus-Averaged", - linewidth=4, + linewidth=6, color='tab:green', linestyle = "solid", alpha = alpha, + zorder = 1, ) -# ax0.plot( -# wind_speeds, -# mit_Ct_rotor_madsen, -# label="MITRotor Madsen Rotor-Averaged", -# linewidth=4, -# color='tab:purple', -# linestyle = "solid", -# alpha = alpha, -# ) -# ax0.plot( -# wind_speeds, -# mit_Ct_annulus_madsen, -# label="MITRotor Madsen Annulus-Averaged", -# linewidth=4, -# color='tab:red', -# linestyle = "solid", -# alpha = alpha, -# ) -ax0.plot( + +ax0.scatter( wind_speeds, floris_Ct_rotor_umm, label="FLORIS-MITRotor UMM Rotor-Averaged", - linewidth=4, color='tab:blue', - linestyle = "dashed", alpha = alpha, + marker = "o", + zorder = 2, + s = 80, ) -ax0.plot( +ax0.scatter( wind_speeds, floris_Ct_annulus_umm, label="FLORIS-MITRotor UMM Annulus-Averaged", - linewidth=4, color='tab:green', - linestyle = "dashed", alpha = alpha, + zorder = 2, + s = 80, + marker = "s" ) - -ax0.plot( +ax0.scatter( wind_speeds, - floris_Ct_rotor_madsen, - label="FLORIS-MITRotor Madsen Rotor-Averaged", - linewidth=4, - color='tab:purple', - linestyle = "dashed", - alpha = alpha, -) -ax0.plot( - wind_speeds, - floris_Ct_annulus_madsen, - label="FLORIS-MITRotor Madsen Annulus-Averaged", - linewidth=4, + floris_Ct_annulus_umm_LUT, + label="FLORIS-MITRotor UMM LUT Annulus-Averaged", color='tab:red', - linestyle = "dashed", alpha = alpha, + zorder = 2, + s = 80, + marker = "v" ) -ax0.set_xlabel("Wind Speed [m/s]", size = 16) -ax0.set_ylabel("$C_T$", size = 16) -ax0.tick_params(labelsize = 14) -ax0.set_title("$C_T$", size = 18) +ax0.set_xlabel("Wind Speed [m/s]") +ax0.set_ylabel("$C_T$") +ax0.tick_params() +ax0.set_title("$C_T$") # plot Cp values against one another and against IEA15MW from figure 3.1-C (https://docs.nrel.gov/docs/fy20osti/75698.pdf) ax1.plot( wind_table, df["Aero Power Coefficient [-]"].to_list(), label="IEA15MW", - linewidth=4, + linewidth=6, color='tab:orange', linestyle = "solid", alpha = alpha, + zorder = 1 ) ax1.plot( wind_speeds, mit_Cp_rotor_umm, label="MITRotor UMM Rotor-Averaged", - linewidth=4, + linewidth=6, color='tab:blue', linestyle = "solid", alpha = alpha, + zorder = 1 +) +ax1.plot( + wind_speeds, + mit_Cp_annulus_umm_LUT, + label="MITRotor UMM LUT Annulus-Averaged", + linewidth=6, + color='tab:red', + linestyle = "solid", + alpha = alpha, + zorder = 1 ) ax1.plot( wind_speeds, mit_Cp_annulus_umm, label="MITRotor UMM Annulus-Averaged", - linewidth=4, + linewidth=6, color='tab:green', linestyle = "solid", alpha = alpha, + zorder = 1 ) -# ax1.plot( -# wind_speeds, -# mit_Cp_rotor_madsen, -# label="MITRotor Madsen Rotor-Averaged", -# linewidth=4, -# color='tab:purple', -# linestyle = "solid", -# alpha = alpha, -# ) -# ax1.plot( -# wind_speeds, -# mit_Cp_annulus_madsen, -# label="MITRotor Madsen Annulus-Averaged", -# linewidth=4, -# color='tab:red', -# linestyle = "solid", -# alpha = alpha, -# ) -ax1.plot( + +ax1.scatter( wind_speeds, floris_Cp_rotor_umm, label="FLORIS-MITRotor UMM Rotor-Averaged", - linewidth=4, color='tab:blue', - linestyle = "dashed", + marker = "o", alpha = alpha, + s = 80, + zorder = 2 ) -ax1.plot( +ax1.scatter( wind_speeds, floris_Cp_annulus_umm, label="FLORIS-MITRotor UMM Annulus-Averaged", - linewidth=4, color='tab:green', - linestyle = "dashed", + marker = "s", alpha = alpha, + s = 80, + zorder = 2 ) -ax1.plot( - wind_speeds, - floris_Cp_rotor_madsen, - label="FLORIS-MITRotor Madsen Rotor-Averaged", - linewidth=4, - color='tab:purple', - linestyle = "dashed", - alpha = alpha, -) -ax1.plot( +ax1.scatter( wind_speeds, - floris_Cp_annulus_madsen, - label="FLORIS-MITRotor Madsen Annulus-Averaged", - linewidth=4, + floris_Cp_annulus_umm_LUT, + label="FLORIS-MITRotor UMM LUT Annulus-Averaged", color='tab:red', - linestyle = "dashed", + marker = "v", alpha = alpha, + s = 80, + zorder = 2 ) -ax1.set_xlabel("Wind Speed [m/s]", size = 16) -ax1.set_ylabel("$C_P$", size = 16) -ax1.tick_params(labelsize = 14) -ax1.set_title("$C_P$", size = 18) +ax1.set_xlabel("Wind Speed [m/s]") +ax1.set_ylabel("$C_P$") +ax1.set_title("$C_P$") ax1.legend( - fontsize=14, + fontsize=16, loc="upper right", ) -plt.savefig(figdir / "example_5_IEA15mw_CT_CP.png", dpi=300) +plt.savefig(figdir / "example_6_IEA15mw_CT_CP.png", dpi=300) \ No newline at end of file diff --git a/examples/example_timing.py b/examples/example_timing.py new file mode 100644 index 0000000..b3d628f --- /dev/null +++ b/examples/example_timing.py @@ -0,0 +1,12 @@ +import numpy as np +import polars as pl +import pytest +from pathlib import Path +import matplotlib.pyplot as plt +from MITRotor.Momentum import UnifiedMomentumLUT, UnifiedMomentum +from MITRotor import BEM, IEA15MW, BEMGeometry +import time + + +# use the same (easily convering example and up the number of setpoints and see how it scales) +# try a range of examples and see how slowly they converge \ No newline at end of file From f6f036889e48add64a58ca119fa14fcee889e94d Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Sun, 1 Mar 2026 12:56:12 -0500 Subject: [PATCH 16/19] Add in example timing script --- examples/example_timing.py | 81 +++++++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 5 deletions(-) diff --git a/examples/example_timing.py b/examples/example_timing.py index b3d628f..7f424d5 100644 --- a/examples/example_timing.py +++ b/examples/example_timing.py @@ -1,12 +1,83 @@ import numpy as np -import polars as pl -import pytest from pathlib import Path -import matplotlib.pyplot as plt from MITRotor.Momentum import UnifiedMomentumLUT, UnifiedMomentum +from MITRotor.TipLoss import NoTipLoss from MITRotor import BEM, IEA15MW, BEMGeometry +import pandas as pd import time +# Floris imports +from floris import FlorisModel, TimeSeries +from MITRotor.FlorisInterface.FlorisInterface import MITRotorTurbine, default_bem_factory -# use the same (easily convering example and up the number of setpoints and see how it scales) -# try a range of examples and see how slowly they converge \ No newline at end of file +bem_rotor_umm = MITRotorTurbine() +bem_annulus_umm_LUT = BEM( + rotor=IEA15MW(), + momentum_model=UnifiedMomentumLUT(averaging="annulus", cache_fn = Path("cache")/ "lut.csv"), + geometry=BEMGeometry(Nr=10, Ntheta=20), + tiploss_model=NoTipLoss(), +) + +bem_rotor_times = [] +bem_annulus_LUT_times = [] +ns = [5 * i for i in range(1, 20)] +for n in ns: + print(f"{n} wind speeds") + wind_speeds = np.linspace(5, 20, n) + wind_dirs = np.full_like(wind_speeds, 270.0) + turbulence_intensity = np.zeros_like(wind_speeds) + + time_series = TimeSeries( + wind_speeds=wind_speeds, + wind_directions=wind_dirs, + turbulence_intensities=turbulence_intensity, + ) + + fmodel_rotor_umm = FlorisModel("defaults") + fmodel_rotor_umm.set(layout_x = [0.0], layout_y = [0.0], wind_data = time_series) + fmodel_rotor_umm.set_operation_model(bem_rotor_umm) # default bem_model uses rotor-averaging + floris_rotor_umm_start = time.time() + fmodel_rotor_umm.run() + floris_rotor_umm_end = time.time() + dt_rotor = floris_rotor_umm_end - floris_rotor_umm_start + print("FLORIS UMM-BEM Rotor-Averaged: " + str(dt_rotor) + " seconds") + bem_rotor_times.append(dt_rotor) + + # solve FLORIS with UMM-BEM with LUT though MITRotor - annulus averaged + fmodel_annulus_umm_LUT = FlorisModel("defaults") + fmodel_annulus_umm_LUT.set(layout_x = [0.0], layout_y = [0.0], wind_data = time_series) + fmodel_annulus_umm_LUT.set_operation_model(MITRotorTurbine(bem_model = bem_annulus_umm_LUT)) # default bem_model uses rotor-averaging + floris_annulus_umm_LUT_start = time.time() + fmodel_annulus_umm_LUT.run() + floris_annulus_umm_LUT_end = time.time() + dt_annulus_LUT = floris_annulus_umm_LUT_end - floris_annulus_umm_LUT_start + print("FLORIS UMM-BEM LUT Annulus-Averaged: " + str(dt_annulus_LUT) + " seconds") + bem_annulus_LUT_times.append(dt_annulus_LUT) + + +rows = [] + +for n, dt in zip(ns, bem_rotor_times): + rows.append({ + "n_wind_speeds": n, + "runtime_seconds": dt, + "model": "rotor_umm", + "vectorized": False + }) + +for n, dt in zip(ns, bem_annulus_LUT_times): + rows.append({ + "n_wind_speeds": n, + "runtime_seconds": dt, + "model": "annulus_lut", + "vectorized": False + }) + +df = pd.DataFrame(rows) + +csv_path = Path("cache")/ "timing_results.csv" + +if csv_path.exists(): + df.to_csv(csv_path, mode="a", header=False, index=False) +else: + df.to_csv(csv_path, index=False) \ No newline at end of file From b2c1094c56810242766eccc99a56c6fcb7742ea2 Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Sun, 1 Mar 2026 14:09:13 -0500 Subject: [PATCH 17/19] Add in plotting code and fix errors in timing code --- examples/example_timing.py | 60 ++++++++++++++++--- examples/example_timing_plots.py | 99 ++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+), 7 deletions(-) create mode 100644 examples/example_timing_plots.py diff --git a/examples/example_timing.py b/examples/example_timing.py index 7f424d5..169e3d7 100644 --- a/examples/example_timing.py +++ b/examples/example_timing.py @@ -10,22 +10,29 @@ from floris import FlorisModel, TimeSeries from MITRotor.FlorisInterface.FlorisInterface import MITRotorTurbine, default_bem_factory -bem_rotor_umm = MITRotorTurbine() +bem_rotor_umm = default_bem_factory() bem_annulus_umm_LUT = BEM( rotor=IEA15MW(), momentum_model=UnifiedMomentumLUT(averaging="annulus", cache_fn = Path("cache")/ "lut.csv"), geometry=BEMGeometry(Nr=10, Ntheta=20), tiploss_model=NoTipLoss(), ) +rotor_area = np.pi * bem_rotor_umm.rotor.R**2 bem_rotor_times = [] bem_annulus_LUT_times = [] -ns = [5 * i for i in range(1, 20)] +wind_speeds_all = [] +bem_rotor_values = [] +bem_annulus_LUT_values = [] +ns = [5 * i for i in range(1, 21)] for n in ns: print(f"{n} wind speeds") wind_speeds = np.linspace(5, 20, n) wind_dirs = np.full_like(wind_speeds, 270.0) turbulence_intensity = np.zeros_like(wind_speeds) + wind_speeds_all.extend( + np.squeeze(wind_speeds) + ) time_series = TimeSeries( wind_speeds=wind_speeds, @@ -35,13 +42,17 @@ fmodel_rotor_umm = FlorisModel("defaults") fmodel_rotor_umm.set(layout_x = [0.0], layout_y = [0.0], wind_data = time_series) - fmodel_rotor_umm.set_operation_model(bem_rotor_umm) # default bem_model uses rotor-averaging + fmodel_rotor_umm.set_operation_model(MITRotorTurbine(bem_model = bem_rotor_umm)) # default bem_model uses rotor-averaging floris_rotor_umm_start = time.time() fmodel_rotor_umm.run() floris_rotor_umm_end = time.time() dt_rotor = floris_rotor_umm_end - floris_rotor_umm_start print("FLORIS UMM-BEM Rotor-Averaged: " + str(dt_rotor) + " seconds") bem_rotor_times.append(dt_rotor) + floris_Cp_rotor_umm = np.squeeze(fmodel_rotor_umm.get_turbine_powers()) / (0.5 * 1.225 * rotor_area * (wind_speeds)**3) + bem_rotor_values.extend( + np.squeeze(floris_Cp_rotor_umm) + ) # solve FLORIS with UMM-BEM with LUT though MITRotor - annulus averaged fmodel_annulus_umm_LUT = FlorisModel("defaults") @@ -53,8 +64,13 @@ dt_annulus_LUT = floris_annulus_umm_LUT_end - floris_annulus_umm_LUT_start print("FLORIS UMM-BEM LUT Annulus-Averaged: " + str(dt_annulus_LUT) + " seconds") bem_annulus_LUT_times.append(dt_annulus_LUT) + floris_Cp_annulus_umm_LUT = np.squeeze(fmodel_annulus_umm_LUT.get_turbine_powers()) / (0.5 * 1.225 * rotor_area * (wind_speeds)**3) + bem_annulus_LUT_values.extend( + np.squeeze(floris_Cp_annulus_umm_LUT) + ) - +# make timing CSV +vectorized = False rows = [] for n, dt in zip(ns, bem_rotor_times): @@ -62,7 +78,7 @@ "n_wind_speeds": n, "runtime_seconds": dt, "model": "rotor_umm", - "vectorized": False + "vectorized": vectorized }) for n, dt in zip(ns, bem_annulus_LUT_times): @@ -70,7 +86,7 @@ "n_wind_speeds": n, "runtime_seconds": dt, "model": "annulus_lut", - "vectorized": False + "vectorized": vectorized }) df = pd.DataFrame(rows) @@ -80,4 +96,34 @@ if csv_path.exists(): df.to_csv(csv_path, mode="a", header=False, index=False) else: - df.to_csv(csv_path, index=False) \ No newline at end of file + df.to_csv(csv_path, index=False) + +# make values CSV +rows = [] +# Rotor +for wind, val in zip(wind_speeds_all, bem_rotor_values): + rows.append({ + "wind_speed": wind, + "power": val, + "model": "rotor_umm", + "vectorized": vectorized + }) + +# Annulus LUT +for wind, val in zip(wind_speeds_all, bem_annulus_LUT_values): + rows.append({ + "wind_speed": wind, + "power": val, + "model": "annulus_lut", + "vectorized": vectorized + }) + +df = pd.DataFrame(rows) + +csv_path = Path("cache") / "value_results.csv" + +if csv_path.exists(): + df.to_csv(csv_path, mode="a", header=False, index=False) +else: + df.to_csv(csv_path, index=False) + diff --git a/examples/example_timing_plots.py b/examples/example_timing_plots.py new file mode 100644 index 0000000..3e52526 --- /dev/null +++ b/examples/example_timing_plots.py @@ -0,0 +1,99 @@ +import pandas as pd +import matplotlib.pyplot as plt +from pathlib import Path + +# ---- Load data ---- +figdir = Path("fig") +time_df = pd.read_csv(Path("cache")/ "timing_results.csv") +value_df = pd.read_csv(Path("cache")/ "value_results.csv") + +#------------------------------------ +# Timing plot +#------------------------------------ +df_avg = ( + time_df.groupby(["n_wind_speeds", "model", "vectorized"], as_index=False) + .agg( + runtime_mean=("runtime_seconds", "mean"), + runtime_std=("runtime_seconds", "std"), + ) +) + +# ---- Create label column for plotting ---- +def make_label(row): + base = { + "rotor_umm": "UMM Rotor-Averaged", + "annulus_lut": "UMM LUT Annulus-Averaged", + }[row["model"]] + + if row["vectorized"]: + return base + " (Vectorized)" + else: + return base + +df_avg["label"] = df_avg.apply(make_label, axis=1) + +label_order = [ + "UMM Rotor-Averaged", + "UMM LUT Annulus-Averaged", + "UMM Rotor-Averaged (Vectorized)", + "UMM LUT Annulus-Averaged (Vectorized)", +] + +# ---- Plot ---- +plt.figure(figsize=(8, 6)) + +for label in label_order: + group = df_avg[df_avg["label"] == label] + group = group.sort_values("n_wind_speeds") + + plt.errorbar( + group["n_wind_speeds"], + group["runtime_mean"], + yerr=group["runtime_std"], + marker="o", + capsize=3, + label=label, + ) + +plt.xlabel("Number of Wind Speeds") +plt.ylabel("Runtime (seconds)") +plt.title("Runtime vs Number of Wind Speeds") +plt.legend() +plt.grid(True) +plt.tight_layout() +plt.savefig(figdir / "example_timings.png", dpi=300) + +#------------------------------------ +# Value plot +#------------------------------------ +plt.figure(figsize=(8, 6)) + +df_avg = ( + value_df.groupby(["wind_speed", "model", "vectorized"], as_index=False) + .agg( + power_mean=("power", "mean"), + power_std=("power", "std"), + ) +) +df_avg["label"] = df_avg.apply(make_label, axis=1) + +for label in label_order: + group = df_avg[df_avg["label"] == label] + group = group.sort_values("wind_speed") + + plt.errorbar( + group["wind_speed"], + group["power_mean"], + yerr=group["power_std"], + marker="o", + capsize=3, + label=label, + ) + +plt.xlabel("Wind Speed") +plt.ylabel("Coefficent of Power $C_P$") +plt.title("$C_P$ vs Wind Speed") +plt.legend() +plt.grid(True) +plt.tight_layout() +plt.savefig(figdir / "example_values.png", dpi=300) \ No newline at end of file From 3659c291c9747e40c79c57d6ba32293dd39fbda5 Mon Sep 17 00:00:00 2001 From: Skylar Gering Date: Sun, 1 Mar 2026 14:22:25 -0500 Subject: [PATCH 18/19] Update timing plots --- examples/example_timing_plots.py | 37 +++++++++++++++----------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/examples/example_timing_plots.py b/examples/example_timing_plots.py index 3e52526..0bc9835 100644 --- a/examples/example_timing_plots.py +++ b/examples/example_timing_plots.py @@ -40,7 +40,7 @@ def make_label(row): ] # ---- Plot ---- -plt.figure(figsize=(8, 6)) +plt.figure(figsize=(6, 4)) for label in label_order: group = df_avg[df_avg["label"] == label] @@ -53,9 +53,11 @@ def make_label(row): marker="o", capsize=3, label=label, + linewidth = 2, ) + # plt.yscale("log") -plt.xlabel("Number of Wind Speeds") +plt.xlabel("Number of Wind Speeds Run\n(evenly-spaced between 5-20 m/s)") plt.ylabel("Runtime (seconds)") plt.title("Runtime vs Number of Wind Speeds") plt.legend() @@ -66,32 +68,27 @@ def make_label(row): #------------------------------------ # Value plot #------------------------------------ -plt.figure(figsize=(8, 6)) +plt.figure(figsize=(6, 4)) -df_avg = ( - value_df.groupby(["wind_speed", "model", "vectorized"], as_index=False) - .agg( - power_mean=("power", "mean"), - power_std=("power", "std"), - ) -) -df_avg["label"] = df_avg.apply(make_label, axis=1) +value_df["label"] = value_df.apply(make_label, axis=1) for label in label_order: - group = df_avg[df_avg["label"] == label] + group = value_df[value_df["label"] == label] group = group.sort_values("wind_speed") - - plt.errorbar( + is_vectorized = group["vectorized"].iloc[0] + linestyle = "dashed" if is_vectorized else "solid" + zorder = 2 if is_vectorized else 1 + plt.plot( group["wind_speed"], - group["power_mean"], - yerr=group["power_std"], - marker="o", - capsize=3, + group["power"], + linewidth = 3, label=label, + linestyle = linestyle, + zorder = zorder, ) -plt.xlabel("Wind Speed") -plt.ylabel("Coefficent of Power $C_P$") +plt.xlabel("Wind Speed [m/s]") +plt.ylabel("Coefficent of Power ($C_P$)") plt.title("$C_P$ vs Wind Speed") plt.legend() plt.grid(True) From 57ff90faa7530a4f02cdfd1e508e46e704651046 Mon Sep 17 00:00:00 2001 From: Skylar A Gering Date: Fri, 10 Apr 2026 11:07:31 -0400 Subject: [PATCH 19/19] MIT Rotor Vectorization (#20) * Attempt at vecotization in pre-process * Working through initial 2 turbine test * Working with 10x speedup for rotor, 2x slowdown for annulus * Vectorization working with Np as the first axis * Fixed some tests with float input, but needs more work * Updated example 6 to include LUT example * Time vectorized code * Fix example timing script * All tests pass, other than new dimensional tests * Vectorization complete * Clean up BEM tests --- MITRotor/Aerodynamics.py | 11 +- MITRotor/BEMSolver.py | 88 ++++++++---- MITRotor/FlorisInterface/FlorisInterface.py | 27 ++-- MITRotor/Geometry.py | 53 +++++++- MITRotor/Momentum.py | 28 ++-- MITRotor/TangentialInduction.py | 5 +- examples/example_02_rotor_distributions.py | 2 +- .../example_04_yaw_tilt_rotor_comparison.py | 2 +- examples/example_06_floris_integration.py | 20 +-- examples/example_07_LUT_timing.py | 128 ++++++++++++++++++ tests/test_bem.py | 73 +++++++++- 11 files changed, 348 insertions(+), 89 deletions(-) create mode 100644 examples/example_07_LUT_timing.py diff --git a/MITRotor/Aerodynamics.py b/MITRotor/Aerodynamics.py index 265872c..bd761a0 100644 --- a/MITRotor/Aerodynamics.py +++ b/MITRotor/Aerodynamics.py @@ -7,7 +7,7 @@ from numpy.typing import ArrayLike from .RotorDefinition import RotorDefinition -from .Geometry import BEMGeometry +from .Geometry import BEMGeometry, expand_to_Nr_Ntheta from UnifiedMomentumModel.Utilities.Geometry import calc_eff_yaw __all__ = [ @@ -269,13 +269,16 @@ def __call__( AerodynamicProperties: Calculated aerodynamic properties stored in AerodynamicProperties object. """ + tsr = expand_to_Nr_Ntheta(tsr) + pitch = expand_to_Nr_Ntheta(pitch) # calculate values in "yaw-only" frame local_yaw = -self.eff_yaw Vax = U * ((1 - an) * np.cos(local_yaw)) + theta_eff = geom.theta_mesh + self.delta_theta Vtan = ( (1 + aprime) * tsr * geom.mu_mesh - U * (1 - an) - * np.cos(self.eff_theta_mesh) + * np.cos(theta_eff) * np.sin(local_yaw) ) @@ -291,8 +294,8 @@ def __call__( an = an, aprime = aprime, solidity = solidity, - U = U * np.ones(geom.shape), - wdir = wdir * np.ones(geom.shape), + U = U * np.ones_like(geom.mu_mesh), + wdir = wdir * np.ones_like(geom.mu_mesh), Vax = Vax, Vtan = Vtan, aoa = aoa, diff --git a/MITRotor/BEMSolver.py b/MITRotor/BEMSolver.py index daea9bc..7576268 100644 --- a/MITRotor/BEMSolver.py +++ b/MITRotor/BEMSolver.py @@ -7,12 +7,13 @@ from . import Momentum, TipLoss from .Aerodynamics import AerodynamicModel, AerodynamicProperties, DefaultAerodynamics -from .Geometry import BEMGeometry +from .Geometry import BEMGeometry, expand_to_Np, expand_to_Nr_Ntheta from .RotorDefinition import RotorDefinition from .TangentialInduction import DefaultTangentialInduction, TangentialInductionModel from UnifiedMomentumModel.Utilities.Geometry import calc_eff_yaw + def average(geometry: BEMGeometry, value: ArrayLike, grid: Literal["sector", "annulus", "rotor"] = "rotor"): # Assuming the function returns a 2D grid of values @@ -58,13 +59,13 @@ def solidity(self, grid: Literal["sector ", "annulus", "rotor"] = "rotor"): def U(self, grid: Literal["sector", "annulus", "rotor"] = "rotor"): return average(self.geom, self.aero_props.U, grid) - def wdir(self, grid: Literal["sector ", "annulus", "rotor"] = "rotor"): + def wdir(self, grid: Literal["sector", "annulus", "rotor"] = "rotor"): return average(self.geom, self.aero_props.wdir, grid) def Vax(self, grid: Literal["sector", "annulus", "rotor"] = "rotor"): return average(self.geom, self.aero_props.Vax, grid) - def Vtan(self, grid: Literal["sector ", "annulus", "rotor"] = "rotor"): + def Vtan(self, grid: Literal["sector", "annulus", "rotor"] = "rotor"): return average(self.geom, self.aero_props.Vtan, grid) def W(self, grid: Literal["sector", "annulus", "rotor"] = "rotor"): @@ -91,29 +92,27 @@ def Ctan(self, grid: Literal["sector", "annulus", "rotor"] = "rotor"): def Cx(self, grid: Literal["sector", "annulus", "rotor"] = "rotor"): return average(self.geom, self.aero_props.C_x_corr, grid) - def Ctau(self, grid: Literal["sector ", "annulus", "rotor"] = "rotor"): + def Ctau(self, grid: Literal["sector", "annulus", "rotor"] = "rotor"): return average(self.geom, self.aero_props.C_tau_corr, grid) - def Ctau_uncorr(self, grid: Literal["sector ", "annulus", "rotor"] = "rotor"): + def Ctau_uncorr(self, grid: Literal["sector", "annulus", "rotor"] = "rotor"): return average(self.geom, self.aero_props.C_tau, grid) def F(self, grid: Literal["sector", "annulus", "rotor"] = "rotor"): return average(self.geom, self.aero_props.F, grid) def Cp(self, grid: Literal["sector", "annulus", "rotor"] = "rotor"): - dCp = ( - self.tsr - * self.geom.mu_mesh - * self.Ctau_uncorr(grid="sector") - ) + tsr = np.asarray(self.tsr) + if tsr.ndim == 1: + tsr = expand_to_Nr_Ntheta(tsr) + dCp = (tsr * self.geom.mu_mesh * self.Ctau_uncorr(grid="sector")) return average(self.geom, dCp, grid=grid) def Cp_corr(self, grid: Literal["sector", "annulus", "rotor"] = "rotor"): - dCp = ( - self.tsr - * self.geom.mu_mesh - * self.Ctau(grid="sector") - ) + tsr = np.asarray(self.tsr) + if tsr.ndim == 1: + tsr = expand_to_Nr_Ntheta(tsr) + dCp = (tsr * self.geom.mu_mesh * self.Ctau(grid="sector")) return average(self.geom, dCp, grid=grid) def Ct(self, grid: Literal["sector", "annulus", "rotor"] = "rotor"): @@ -169,21 +168,37 @@ def sample_points(self, yaw: float = 0.0, tilt: float = 0.0) -> tuple[ArrayLike, return X, Y, Z def pre_process(self, pitch, tsr, yaw = 0, tilt = 0, **kwargs): + pitch, tsr = np.asarray(pitch), np.asarray(tsr) + yaw, tilt = np.asarray(yaw), np.asarray(tilt) + self.scalar_inputs = (pitch.ndim == 0) & (tsr.ndim == 0) & (yaw.ndim == 0) & (tilt.ndim == 0) + if not self.scalar_inputs: + assert len(pitch) == len(tsr) == len(yaw) == len(tilt), "Setpoint arrays should be the same lenght" # switch reference frame to a "yaw-only" frame where y' is aligned with the lateral wake - self.aerodynamic_model.eff_yaw = calc_eff_yaw(yaw, tilt) - if tilt == 0: - dtheta = 0 - elif yaw == 0: - dtheta = np.pi / 2 - else: # non-zero yaw and tilt - sin_eff = np.sin(self.aerodynamic_model.eff_yaw) - dtheta = np.arccos(np.sin(yaw) / sin_eff) - self.aerodynamic_model.eff_theta_mesh = self.geometry.theta_mesh + dtheta + yaw, tilt = np.broadcast_arrays(yaw, tilt) + eff_yaw = calc_eff_yaw(yaw, tilt) + # initialize dtheta + dtheta = np.zeros_like(eff_yaw, dtype=float) + # masks + yaw_zero = (yaw == 0) + not_tilt_zero = np.logical_not(tilt == 0) + # case1: yaw == 0 and tilt != 0 + case1 = yaw_zero & not_tilt_zero + dtheta[case1] = np.pi / 2 + # case2: yaw != 0 and tilt != 0 + case2 = np.logical_not(yaw_zero) & not_tilt_zero + dtheta[case2] = np.arccos( + np.sin(yaw[case2]) / np.sin(eff_yaw[case2]) + ) + # expand everything to the correct dimensions to ensure broadcasting + self.aerodynamic_model.eff_yaw = expand_to_Nr_Ntheta(eff_yaw) + self.aerodynamic_model.delta_theta = expand_to_Nr_Ntheta(dtheta) + self.geometry.mu_mesh = expand_to_Np(self.geometry.mu_mesh) + self.geometry.theta_mesh = expand_to_Np(self.geometry.theta_mesh) return def initial_guess(self, *args, **kwargs) -> Tuple[ArrayLike, ...]: - a = (1 / 3) * np.ones(self.geometry.shape) - aprime = np.zeros(self.geometry.shape) + a = (1 / 3) * np.ones_like(self.geometry.mu_mesh) + aprime = np.zeros_like(self.geometry.mu_mesh) return a, aprime @@ -198,8 +213,8 @@ def residual( tilt: ArrayLike = 0.0, ) -> Tuple[ArrayLike, ...]: an, aprime = x - U = np.ones(self.geometry.shape) if U is None else U - wdir = np.zeros(self.geometry.shape) if wdir is None else wdir + U = np.ones_like(self.geometry.mu_mesh) if U is None else U + wdir = np.zeros_like(self.geometry.mu_mesh) if wdir is None else wdir aero_props = self.aerodynamic_model( an = an, @@ -221,12 +236,25 @@ def residual( return e_an, e_aprime def post_process(self, result: FixedPointIterationResult, pitch, tsr, yaw = 0, U=None, wdir=None, tilt = 0.0) -> BEMSolution: - U = np.ones(self.geometry.shape) if U is None else U - wdir = np.zeros(self.geometry.shape) if wdir is None else wdir + U = np.ones_like(self.geometry.mu_mesh) if U is None else U + wdir = np.zeros_like(self.geometry.mu_mesh) if wdir is None else wdir an, aprime = result.x aero_props = self.aerodynamic_model(an, aprime, pitch, tsr, yaw, self.rotor, self.geometry, U, wdir, tilt = tilt) aero_props.F = self.tiploss_model(aero_props, pitch, tsr, yaw, self.rotor, self.geometry, tilt = tilt) avg_Ct = average(self.geometry, aero_props.C_x) u4,v4,w4 = self.momentum_model.compute_initial_wake_velocities(avg_Ct, yaw, tilt = tilt) + if self.scalar_inputs: # if all setpoints were scalars + # return single values as scalars + pitch, tsr, yaw, tilt = [np.asarray(x).item() for x in (pitch, tsr, yaw, tilt)] + u4, v4, w4 = [np.asarray(x).item() for x in (u4, v4, w4)] + # remove unneeded extra axis from Ntheta x Nr arrays + an = np.squeeze(an) + aprime = np.squeeze(aprime) + self.geometry.theta_mesh = np.squeeze(self.geometry.theta_mesh) + self.geometry.mu_mesh = np.squeeze(self.geometry.mu_mesh) + for key, value in vars(aero_props).items(): + if isinstance(value, np.ndarray): + setattr(aero_props, key, np.squeeze(value)) + return BEMSolution(pitch, tsr, yaw, aero_props, self.geometry, result.converged, result.niter, u4, v4, tilt = tilt, w4 = w4) diff --git a/MITRotor/FlorisInterface/FlorisInterface.py b/MITRotor/FlorisInterface/FlorisInterface.py index f496c69..50c2646 100644 --- a/MITRotor/FlorisInterface/FlorisInterface.py +++ b/MITRotor/FlorisInterface/FlorisInterface.py @@ -109,21 +109,18 @@ def _update_solution(self, # calculate rotor area rotor_area = np.pi * self.bem_model.rotor.R**2 - # loop over flow conditions -> TODO: should this be vectorized? - for findex in range(n_findex): - for tindex in range(n_turbines): - # get setpoints - vel = rotor_average_velocities[findex, tindex] - yaw, tilt = np.deg2rad(yaw_angles[findex, tindex]), np.deg2rad(tilt_angles[findex, tindex]) - pitch = np.deg2rad(self.pitch_interp(vel)) - tsr = self.tsr_interp(vel) - # solve BEM - bem_sol = self.bem_model(pitch, tsr, yaw = yaw, tilt = tilt) - # get induction and thrust coeff - self._a[findex, tindex] = bem_sol.a() - self._Ct[findex, tindex] = bem_sol.Ct() - # compute power - self._power[findex, tindex] = 0.5 * bem_sol.Cp() * air_density * rotor_area * (vel)**3 + # get setpoints + yaw, tilt = np.deg2rad(yaw_angles), np.deg2rad(tilt_angles) + pitch = np.deg2rad(self.pitch_interp(rotor_average_velocities)) + tsr = self.tsr_interp(rotor_average_velocities) + for tindex in range(n_turbines): + # solve BEM + bem_sol = self.bem_model(pitch[:, tindex], tsr[:, tindex], yaw = yaw[:, tindex], tilt = tilt[:, tindex]) + # get induction and thrust coeff + self._a[:, tindex] = bem_sol.a() + self._Ct[:, tindex] = bem_sol.Ct() + # compute power + self._power[:, tindex] = 0.5 * bem_sol.Cp() * air_density * rotor_area * (rotor_average_velocities[:, tindex])**3 return def power(self, **kwargs) -> NDArrayFloat: diff --git a/MITRotor/Geometry.py b/MITRotor/Geometry.py index 8a00144..7f0ae3f 100644 --- a/MITRotor/Geometry.py +++ b/MITRotor/Geometry.py @@ -40,14 +40,53 @@ def cartesian(self, yaw: float, tilt: float) -> Tuple[ArrayLike, ...]: Z = self.mu_mesh * np.cos(self.theta_mesh) # vertical return X, Y, Z + +# ---------- Function for averaging over the rotor ---------- # - def annulus_average(self, X: ArrayLike): - X_azim = 1 / (2 * np.pi) * np.trapezoid(X, self.theta_mesh, axis=-1) + def annulus_average(self, X): + X = np.asarray(X) + theta = np.asarray(self.theta).reshape(-1) + #Ensure last axis is Nθ + if X.shape[-1] != theta.shape[0]: + raise ValueError(f"Mismatch: X.shape={X.shape}, theta.shape={theta.shape}") + # Integrate over Nθ (last axis) + return (1 / (2 * np.pi)) * np.trapezoid(X, theta, axis=-1) - return X_azim + def rotor_average(self, X): + X = np.asarray(X) + mu = np.asarray(self.mu).reshape(-1) # (Nr,) + # Ensure last axis is Nr + if X.shape[-1] != mu.shape[0]: + raise ValueError(f"Mismatch: X.shape={X.shape}, mu.shape={mu.shape}") + # Integrate over Nr (last axis) + return 2 * np.trapezoid(X * mu, mu, axis=-1) + +# ---------- Function for adjusting axes for vectorization ---------- # - def rotor_average(self, X: ArrayLike): - # Takes annulus average quantities and performs rotor average +def expand_to_Np(x): # add setpoint axis + x = np.atleast_1d(x) + if x.ndim < 3: + return x[None, ...] + else: + return x - X_rotor = 2 * np.trapezoid(X * self.mu, self.mu) - return X_rotor +def expand_to_Nr_Ntheta(x): # add Nr and Nθ axis + x = np.atleast_1d(x) + if x.ndim < 3: + return x[:, None, None] + else: + return x + +def expand_to_Nr(x): # add Nr axis + x = np.atleast_1d(x) + if x.ndim < 2: + return x[:, None] + else: + return x + +def expand_to_Ntheta(x): # add Nθ axis + x = np.atleast_1d(x) + if x.ndim < 3: + return x[:, :, None] + else: + return x diff --git a/MITRotor/Momentum.py b/MITRotor/Momentum.py index edfb4d9..6834ff0 100644 --- a/MITRotor/Momentum.py +++ b/MITRotor/Momentum.py @@ -8,6 +8,7 @@ from pathlib import Path from UnifiedMomentumModel import Momentum as UMM from UnifiedMomentumModel.Utilities.Geometry import calc_eff_yaw, eff_yaw_inv_rotation +from .Geometry import expand_to_Nr_Ntheta, expand_to_Nr, expand_to_Ntheta if TYPE_CHECKING: from .Geometry import BEMGeometry @@ -62,13 +63,11 @@ def _func_rotor( geom.rotor_average( geom.annulus_average( np.clip(aero_props.C_x_corr, 0, 1.69) - ) - ) + ) + ) ) - - return self.compute_induction(rotor_avg_axial_force, yaw = yaw, tilt = tilt) - - + an = self.compute_induction(rotor_avg_axial_force, yaw = yaw, tilt = tilt) + return expand_to_Nr_Ntheta(an) def _func_annulus( self, @@ -81,15 +80,12 @@ def _func_annulus( tilt: float = 0.0, ) -> ArrayLike: - annulus_avg_axial_force = ( - - geom.annulus_average( - np.clip(aero_props.C_x_corr, -10, 10) - ) - )[:, None] * np.ones(geom.shape) - - - return self.compute_induction(annulus_avg_axial_force, yaw = yaw, tilt = tilt) + annulus_avg_axial_force = geom.annulus_average( + np.clip(aero_props.C_x_corr, 0, 1.69) + ) + yaw, tilt = expand_to_Nr(yaw), expand_to_Nr(tilt) + an = self.compute_induction(annulus_avg_axial_force, yaw = yaw, tilt = tilt) + return expand_to_Ntheta(an) def _func_sector( self, @@ -102,7 +98,7 @@ def _func_sector( tilt: float = 0.0, ) -> ArrayLike: axial_force = np.clip(aero_props.C_x_corr, -10, 10) - + yaw, tilt = expand_to_Nr_Ntheta(yaw), expand_to_Nr_Ntheta(tilt) return self.compute_induction(axial_force, yaw = yaw, tilt = tilt) def __call__( diff --git a/MITRotor/TangentialInduction.py b/MITRotor/TangentialInduction.py index cd493ec..d2dff09 100644 --- a/MITRotor/TangentialInduction.py +++ b/MITRotor/TangentialInduction.py @@ -3,7 +3,7 @@ from numpy.typing import ArrayLike from .Aerodynamics import AerodynamicProperties -from .Geometry import BEMGeometry +from .Geometry import BEMGeometry, expand_to_Nr_Ntheta from .RotorDefinition import RotorDefinition from UnifiedMomentumModel.Utilities.Geometry import calc_eff_yaw @@ -54,7 +54,8 @@ def __call__( geom: BEMGeometry, tilt: float = 0.0, ) -> ArrayLike: - eff_yaw = calc_eff_yaw(yaw, tilt) + eff_yaw = expand_to_Nr_Ntheta(calc_eff_yaw(yaw, tilt)) + tsr = expand_to_Nr_Ntheta(tsr) aprime = ( np.clip(aero_props.C_tau_corr, -2, 2) / (4 * np.maximum(geom.mu_mesh, 0.1) ** 2 * tsr * (1 - aero_props.an) * np.cos(eff_yaw)) diff --git a/examples/example_02_rotor_distributions.py b/examples/example_02_rotor_distributions.py index 517ea21..98e976f 100644 --- a/examples/example_02_rotor_distributions.py +++ b/examples/example_02_rotor_distributions.py @@ -17,7 +17,7 @@ def plot_radial_distributions(sol: BEMSolution, save_to: Path): [ax.legend(loc="lower center") for ax in axes] - axes[-1].set_xlabel("Radial position, $\mu$ [-]") + axes[-1].set_xlabel("Radial position, $\\mu$ [-]") plt.xlim(0, 1) plt.savefig(save_to, dpi=300, bbox_inches="tight") diff --git a/examples/example_04_yaw_tilt_rotor_comparison.py b/examples/example_04_yaw_tilt_rotor_comparison.py index 5b39520..9a809bf 100644 --- a/examples/example_04_yaw_tilt_rotor_comparison.py +++ b/examples/example_04_yaw_tilt_rotor_comparison.py @@ -41,7 +41,7 @@ axes[i, j].set_title(f"r/R ={np.round(r_mesh[0], decimals=2)}") fig.legend( - [f"Yaw ${rounded_deg_misalignment}^\circ$", f"Tilt ${rounded_deg_misalignment}^\circ$", f"Yaw ${np.rad2deg(yaw)}^\circ$ and Tilt ${np.rad2deg(yaw)}^\circ$"], # labels + [f"Yaw ${rounded_deg_misalignment}^\\circ$", f"Tilt ${rounded_deg_misalignment}^\\circ$", f"Yaw ${np.rad2deg(yaw)}^\\circ$ and Tilt ${np.rad2deg(yaw)}^\\circ$"], # labels loc='lower center', ncol=3, bbox_to_anchor=(0.5, 0.05) diff --git a/examples/example_06_floris_integration.py b/examples/example_06_floris_integration.py index 455c23d..e65bf3a 100644 --- a/examples/example_06_floris_integration.py +++ b/examples/example_06_floris_integration.py @@ -110,10 +110,10 @@ pitches = np.deg2rad(pitch_interp(wind_speeds)) tsrs = tsr_interp(wind_speeds) yaws, tilts = np.zeros_like(pitches), np.zeros_like(pitches) -mit_sols_rotor_umm = [bem_rotor_umm(pitch=pitches[i], tsr=tsrs[i], yaw=yaws[i], tilt=tilts[i]) for i in range(len(pitches))] +mit_sols_rotor_umm = bem_rotor_umm(pitch=pitches, tsr=tsrs, yaw=yaws, tilt=tilts) mit_rotor_umm_end = time.time() -mit_Ct_rotor_umm = [sol.Ct() for sol in mit_sols_rotor_umm] -mit_Cp_rotor_umm = [sol.Cp() for sol in mit_sols_rotor_umm] +mit_Ct_rotor_umm = mit_sols_rotor_umm.Ct() +mit_Cp_rotor_umm = mit_sols_rotor_umm.Cp() print("MITRotor UMM-BEM Rotor-Averaged: " + str(mit_rotor_umm_end - mit_rotor_umm_start) + " seconds") # solve UMM-BEM though MITRotor - annulus averaged @@ -124,10 +124,10 @@ tiploss_model=NoTipLoss(), ) mit_annulus_umm_start = time.time() -mit_sols_annulus_umm = [bem_annulus_umm(pitch=pitches[i], tsr=tsrs[i], yaw=yaws[i], tilt=tilts[i]) for i in range(len(pitches))] +mit_sols_annulus_umm = bem_annulus_umm(pitch=pitches, tsr=tsrs, yaw=yaws, tilt=tilts) mit_annulus_umm_end = time.time() -mit_Ct_annulus_umm = [sol.Ct() for sol in mit_sols_annulus_umm] -mit_Cp_annulus_umm = [sol.Cp() for sol in mit_sols_annulus_umm] +mit_Ct_annulus_umm = mit_sols_annulus_umm.Ct() +mit_Cp_annulus_umm = mit_sols_annulus_umm.Cp() print("MITRotor UMM-BEM Annulus-Averaged: " + str(mit_annulus_umm_end - mit_annulus_umm_start) + " seconds") # solve UMM-BEM though MITRotor - sector averaged @@ -153,10 +153,10 @@ tiploss_model=NoTipLoss(), ) mit_annulus_umm_LUT_start = time.time() -mit_sols_annulus_umm_LUT = [bem_annulus_umm_LUT(pitch=pitches[i], tsr=tsrs[i], yaw=yaws[i], tilt=tilts[i]) for i in range(len(pitches))] +mit_sols_annulus_umm_LUT = bem_annulus_umm_LUT(pitch=pitches, tsr=tsrs, yaw=yaws, tilt=tilts) mit_annulus_umm_LUT_end = time.time() -mit_Ct_annulus_umm_LUT = [sol.Ct() for sol in mit_sols_annulus_umm_LUT] -mit_Cp_annulus_umm_LUT = [sol.Cp() for sol in mit_sols_annulus_umm_LUT] +mit_Ct_annulus_umm_LUT = mit_sols_annulus_umm_LUT.Ct() +mit_Cp_annulus_umm_LUT = mit_sols_annulus_umm_LUT.Cp() print("MITRotor UMM-BEM LUT Annulus-Averaged: " + str(mit_annulus_umm_LUT_end - mit_annulus_umm_LUT_start) + " seconds") # solve FLORIS with UMM-BEM though MITRotor - rotor averaged @@ -374,4 +374,4 @@ loc="upper right", ) -plt.savefig(figdir / "example_6_IEA15mw_CT_CP.png", dpi=300) \ No newline at end of file +plt.savefig(figdir / "example_6_IEA15mw_CT_CP.png", dpi=300) diff --git a/examples/example_07_LUT_timing.py b/examples/example_07_LUT_timing.py new file mode 100644 index 0000000..988b814 --- /dev/null +++ b/examples/example_07_LUT_timing.py @@ -0,0 +1,128 @@ +import numpy as np +from pathlib import Path +from MITRotor.Momentum import UnifiedMomentumLUT, UnifiedMomentum +from MITRotor.TipLoss import NoTipLoss +from MITRotor import BEM, IEA15MW, BEMGeometry +import pandas as pd +import time + +# Floris imports +from floris import FlorisModel, TimeSeries +from MITRotor.FlorisInterface.FlorisInterface import MITRotorTurbine, default_bem_factory + +bem_rotor_umm = default_bem_factory() +bem_annulus_umm_LUT = BEM( + rotor=IEA15MW(), + momentum_model=UnifiedMomentumLUT(averaging="annulus", cache_fn = Path("cache")/ "lut.csv"), + geometry=BEMGeometry(Nr=10, Ntheta=20), + tiploss_model=NoTipLoss(), +) +rotor_area = np.pi * bem_rotor_umm.rotor.R**2 + +bem_rotor_times = [] +bem_annulus_LUT_times = [] +wind_speeds_all = [] +bem_rotor_values = [] +bem_annulus_LUT_values = [] +ns = [5 * i for i in range(1, 21)] +for n in ns: + print(f"{n} wind speeds") + wind_speeds = np.linspace(5, 20, n) + wind_dirs = np.full_like(wind_speeds, 270.0) + turbulence_intensity = np.zeros_like(wind_speeds) + wind_speeds_all.extend( + np.squeeze(wind_speeds) + ) + + time_series = TimeSeries( + wind_speeds=wind_speeds, + wind_directions=wind_dirs, + turbulence_intensities=turbulence_intensity, + ) + + fmodel_rotor_umm = FlorisModel("defaults") + fmodel_rotor_umm.set(layout_x = [0.0], layout_y = [0.0], wind_data = time_series) + fmodel_rotor_umm.set_operation_model(MITRotorTurbine(bem_model = bem_rotor_umm)) # default bem_model uses rotor-averaging + floris_rotor_umm_start = time.time() + fmodel_rotor_umm.run() + floris_rotor_umm_end = time.time() + dt_rotor = floris_rotor_umm_end - floris_rotor_umm_start + print("FLORIS UMM-BEM Rotor-Averaged: " + str(dt_rotor) + " seconds") + bem_rotor_times.append(dt_rotor) + floris_Cp_rotor_umm = np.squeeze(fmodel_rotor_umm.get_turbine_powers()) / (0.5 * 1.225 * rotor_area * (wind_speeds)**3) + bem_rotor_values.extend( + np.squeeze(floris_Cp_rotor_umm) + ) + + # solve FLORIS with UMM-BEM with LUT though MITRotor - annulus averaged + fmodel_annulus_umm_LUT = FlorisModel("defaults") + fmodel_annulus_umm_LUT.set(layout_x = [0.0], layout_y = [0.0], wind_data = time_series) + fmodel_annulus_umm_LUT.set_operation_model(MITRotorTurbine(bem_model = bem_annulus_umm_LUT)) # default bem_model uses rotor-averaging + floris_annulus_umm_LUT_start = time.time() + fmodel_annulus_umm_LUT.run() + floris_annulus_umm_LUT_end = time.time() + dt_annulus_LUT = floris_annulus_umm_LUT_end - floris_annulus_umm_LUT_start + print("FLORIS UMM-BEM LUT Annulus-Averaged: " + str(dt_annulus_LUT) + " seconds") + bem_annulus_LUT_times.append(dt_annulus_LUT) + floris_Cp_annulus_umm_LUT = np.squeeze(fmodel_annulus_umm_LUT.get_turbine_powers()) / (0.5 * 1.225 * rotor_area * (wind_speeds)**3) + bem_annulus_LUT_values.extend( + np.squeeze(floris_Cp_annulus_umm_LUT) + ) + +# make timing CSV +vectorized = True +rows = [] + +for n, dt in zip(ns, bem_rotor_times): + rows.append({ + "n_wind_speeds": n, + "runtime_seconds": dt, + "model": "rotor_umm", + "vectorized": vectorized + }) + +for n, dt in zip(ns, bem_annulus_LUT_times): + rows.append({ + "n_wind_speeds": n, + "runtime_seconds": dt, + "model": "annulus_lut", + "vectorized": vectorized + }) + +df = pd.DataFrame(rows) + +csv_path = Path("cache")/ "timing_results.csv" + +if csv_path.exists(): + df.to_csv(csv_path, mode="a", header=False, index=False) +else: + df.to_csv(csv_path, index=False) + +# make values CSV +rows = [] +# Rotor +for wind, val in zip(wind_speeds_all, bem_rotor_values): + rows.append({ + "wind_speed": wind, + "power": val, + "model": "rotor_umm", + "vectorized": vectorized + }) + +# Annulus LUT +for wind, val in zip(wind_speeds_all, bem_annulus_LUT_values): + rows.append({ + "wind_speed": wind, + "power": val, + "model": "annulus_lut", + "vectorized": vectorized + }) + +df = pd.DataFrame(rows) + +csv_path = Path("cache") / "value_results.csv" + +if csv_path.exists(): + df.to_csv(csv_path, mode="a", header=False, index=False) +else: + df.to_csv(csv_path, index=False) diff --git a/tests/test_bem.py b/tests/test_bem.py index b721efd..e58e7f4 100644 --- a/tests/test_bem.py +++ b/tests/test_bem.py @@ -1,4 +1,4 @@ -from MITRotor import BEM, IEA15MW, UnifiedMomentum, BEMGeometry +from MITRotor import BEM, IEA15MW, UnifiedMomentum, UnifiedMomentumLUT, BEMGeometry from UnifiedMomentumModel.Utilities.Geometry import calc_eff_yaw import numpy as np from pytest import approx @@ -6,7 +6,6 @@ def test_IEA15MW(): IEA15MW() - def test_BEM_initialise(): rotor = IEA15MW() BEM(rotor=rotor) @@ -102,4 +101,72 @@ def test_model_yaw_tilt_rotor_phase(): # tilt and yaw should be offset by 90 degrees assert np.isclose(np.abs(theta_mesh[yaw_max_idx] - theta_mesh[tilt_max_idx]), np.pi / 2, atol = deg_atol) # yaw and evenly split yaw/tilt should be offset by 45 degrees - assert np.isclose(np.abs(theta_mesh[yaw_max_idx] - theta_mesh[yaw_and_tilt_max_idx]), np.pi / 4, atol = deg_atol) \ No newline at end of file + assert np.isclose(np.abs(theta_mesh[yaw_max_idx] - theta_mesh[yaw_and_tilt_max_idx]), np.pi / 4, atol = deg_atol) + +def _expected_shape(grid, Np, Nr, Ntheta): + if grid == "rotor": + return () if Np == 0 else (Np,) + elif grid == "annulus": + return (Nr,) if Np == 0 else (Np, Nr) + elif grid == "sector": + return (Nr, Ntheta) if Np == 0 else (Np, Nr, Ntheta) + else: + raise ValueError(grid) + + +def test_BEM_dimensionality(): + Nr, Ntheta = 20, 40 + rotor = IEA15MW() + + bems = [ + BEM(rotor=rotor, + momentum_model=UnifiedMomentum(averaging="rotor"), + geometry=BEMGeometry(Nr=Nr, Ntheta=Ntheta)), + + BEM(rotor=rotor, + momentum_model=UnifiedMomentumLUT(averaging="annulus"), + geometry=BEMGeometry(Nr=Nr, Ntheta=Ntheta)), + + BEM(rotor=rotor, + momentum_model=UnifiedMomentumLUT(averaging="sector"), + geometry=BEMGeometry(Nr=Nr, Ntheta=Ntheta)), + ] + + # --- inputs --- + pitch_s, tsr_s, yaw_s, tilt_s = 0.0, 7.0, 0.0, 0.0 + + pitch_v = np.array([0.0, 0.1, 0.2]) + tsr_v = np.array([6.0, 7.0, 8.0]) + yaw_v = np.array([0.0, 0.1, 0.2]) + tilt_v = np.array([0.0, -0.1, -0.2]) + + cases = [ + (pitch_s, tsr_s, yaw_s, tilt_s, 0), + (pitch_v, tsr_v, yaw_v, tilt_v, 3), + ] + + fields = ["Cp", "Cp_corr", "Ct", "a", "aoa"] + + for pitch, tsr, yaw, tilt, Np in cases: + for bem in bems: + sol = bem(pitch, tsr, yaw=yaw, tilt=tilt) + + # ========================= + # 1. u4, w4 dimensionality + # ========================= + u4 = np.asarray(sol.u4) + w4 = np.asarray(sol.w4) + + expected = () if Np == 0 else (Np,) + assert u4.shape == expected + assert w4.shape == expected + + # ========================= + # 2. Shape checks for fields + # ========================= + for grid in ["rotor", "annulus", "sector"]: + expected_shape = _expected_shape(grid, Np, Nr, Ntheta) + + for name in fields: + val = np.asarray(getattr(sol, name)(grid=grid)) + assert val.shape == expected_shape, f"{name}, {grid}"