diff --git a/.gitignore b/.gitignore index 94ed528..ea699ed 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,7 @@ coverage.xml .hypothesis/ .pytest_cache/ cover/ +*junit* # Translations *.mo @@ -75,6 +76,7 @@ instance/ # Sphinx documentation docs/_build/ +docs/autogen/ # PyBuilder .pybuilder/ diff --git a/AUTHORS.rst b/AUTHORS.rst index 84e6ec3..2d3ae14 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -2,3 +2,4 @@ Contributors ============ * Arek Drabik +* Jan Bronicki diff --git a/poetry.lock b/poetry.lock index 3774ba9..c04b62c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -34,10 +34,10 @@ python-versions = ">=3.5" dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] -tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] +tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] [[package]] -name = "babel" +name = "Babel" version = "2.10.3" description = "Internationalization utilities" category = "dev" @@ -73,7 +73,7 @@ uvloop = ["uvloop (>=0.15.2)"] name = "certifi" version = "2022.9.24" description = "Python package for providing Mozilla's CA Bundle." -category = "dev" +category = "main" optional = false python-versions = ">=3.6" @@ -86,7 +86,7 @@ optional = false python-versions = ">=3.6.0" [package.extras] -unicode-backport = ["unicodedata2"] +unicode_backport = ["unicodedata2"] [[package]] name = "click" @@ -101,11 +101,29 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "colorama" -version = "0.4.5" +version = "0.4.6" description = "Cross-platform colored terminal text." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" + +[[package]] +name = "contourpy" +version = "1.0.5" +description = "Python library for calculating contours of 2D quadrilateral grids" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +numpy = ">=1.16" + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["docutils (<0.18)", "sphinx", "sphinx-rtd-theme"] +test = ["Pillow", "flake8", "isort", "matplotlib", "pytest"] +test-minimal = ["pytest"] +test-no-codebase = ["Pillow", "matplotlib", "pytest"] [[package]] name = "coverage" @@ -121,6 +139,14 @@ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.1 [package.extras] toml = ["tomli"] +[[package]] +name = "cycler" +version = "0.11.0" +description = "Composable style cycles" +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "dill" version = "0.3.6" @@ -148,6 +174,17 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "exceptiongroup" +version = "1.0.0" +description = "Backport of PEP 654 (exception groups)" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +test = ["pytest (>=6)"] + [[package]] name = "filelock" version = "3.8.0" @@ -160,6 +197,28 @@ python-versions = ">=3.7" docs = ["furo (>=2022.6.21)", "sphinx (>=5.1.1)", "sphinx-autodoc-typehints (>=1.19.1)"] testing = ["covdefaults (>=2.2)", "coverage (>=6.4.2)", "pytest (>=7.1.2)", "pytest-cov (>=3)", "pytest-timeout (>=2.1)"] +[[package]] +name = "fonttools" +version = "4.38.0" +description = "Tools to manipulate font files" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=14.0.0)", "xattr", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres", "scipy"] +lxml = ["lxml (>=4.0,<5)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.23.0)"] +symfont = ["sympy"] +type1 = ["xattr"] +ufo = ["fs (>=2.2.0,<3)"] +unicode = ["unicodedata2 (>=14.0.0)"] +woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] + [[package]] name = "idna" version = "3.4" @@ -168,6 +227,23 @@ category = "dev" optional = false python-versions = ">=3.5" +[[package]] +name = "igrf" +version = "13.0.2" +description = "IGRF13, IGRF12, IGRF11 models with simple object-oriented Python interface." +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +numpy = "*" +xarray = "*" + +[package.extras] +lint = ["flake8", "flake8-blind-except", "flake8-bugbear", "flake8-builtins", "mypy", "types-python-dateutil"] +plot = ["matplotlib"] +tests = ["pytest"] + [[package]] name = "imagesize" version = "1.4.1" @@ -210,12 +286,12 @@ python-versions = ">=3.6.1,<4.0" [package.extras] colors = ["colorama (>=0.4.3,<0.5.0)"] -pipfile-deprecated-finder = ["pipreqs", "requirementslib"] +pipfile_deprecated_finder = ["pipreqs", "requirementslib"] plugins = ["setuptools"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] +requirements_deprecated_finder = ["pip-api", "pipreqs"] [[package]] -name = "jinja2" +name = "Jinja2" version = "3.1.2" description = "A very fast and expressive template engine." category = "dev" @@ -228,22 +304,61 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "jplephem" +version = "2.18" +description = "Use a JPL ephemeris to predict planet positions." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +numpy = "*" + +[[package]] +name = "kiwisolver" +version = "1.4.4" +description = "A fast implementation of the Cassowary constraint solver" +category = "main" +optional = false +python-versions = ">=3.7" + [[package]] name = "lazy-object-proxy" -version = "1.7.1" +version = "1.8.0" description = "A fast and thorough lazy object proxy." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] -name = "markupsafe" +name = "MarkupSafe" version = "2.1.1" description = "Safely add untrusted strings to HTML/XML markup." category = "dev" optional = false python-versions = ">=3.7" +[[package]] +name = "matplotlib" +version = "3.6.1" +description = "Python plotting package" +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +kiwisolver = ">=1.0.1" +numpy = ">=1.19" +packaging = ">=20.0" +pillow = ">=6.2.0" +pyparsing = ">=2.2.1" +python-dateutil = ">=2.7" +setuptools_scm = ">=7" + [[package]] name = "mccabe" version = "0.7.0" @@ -278,17 +393,44 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "numpy" +version = "1.23.4" +description = "NumPy is the fundamental package for array computing with Python." +category = "main" +optional = false +python-versions = ">=3.8" + [[package]] name = "packaging" version = "21.3" description = "Core utilities for Python packages" -category = "dev" +category = "main" optional = false python-versions = ">=3.6" [package.dependencies] pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" +[[package]] +name = "pandas" +version = "1.5.1" +description = "Powerful data structures for data analysis, time series, and statistics" +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +numpy = [ + {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, + {version = ">=1.20.3", markers = "python_version < \"3.10\""}, +] +python-dateutil = ">=2.8.1" +pytz = ">=2020.1" + +[package.extras] +test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] + [[package]] name = "pathspec" version = "0.10.1" @@ -297,6 +439,18 @@ category = "dev" optional = false python-versions = ">=3.7" +[[package]] +name = "Pillow" +version = "9.3.0" +description = "Python Imaging Library (Fork)" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-issues (>=3.0.1)", "sphinx-removed-in", "sphinxext-opengraph"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] + [[package]] name = "platformdirs" version = "2.5.2" @@ -330,7 +484,7 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] -name = "pygments" +name = "Pygments" version = "2.13.0" description = "Pygments is a syntax highlighting package written in Python." category = "dev" @@ -367,7 +521,7 @@ testutils = ["gitpython (>3)"] name = "pyparsing" version = "3.0.9" description = "pyparsing module - Classes and methods to define and execute parsing grammars" -category = "dev" +category = "main" optional = false python-versions = ">=3.6.8" @@ -376,7 +530,7 @@ diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pytest" -version = "7.1.3" +version = "7.2.0" description = "pytest: simple powerful testing with Python" category = "dev" optional = false @@ -385,11 +539,11 @@ python-versions = ">=3.7" [package.dependencies] attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -tomli = ">=1.0.0" +tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] @@ -423,11 +577,22 @@ pytest = ">=5.0" [package.extras] dev = ["pre-commit", "pytest-asyncio", "tox"] +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" + +[package.dependencies] +six = ">=1.5" + [[package]] name = "pytz" version = "2022.5" description = "World timezone definitions, modern and historical" -category = "dev" +category = "main" optional = false python-versions = "*" @@ -447,16 +612,85 @@ urllib3 = ">=1.21.1,<1.27" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "scipy" +version = "1.9.3" +description = "Fundamental algorithms for scientific computing in Python" +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +numpy = ">=1.18.5,<1.26.0" + +[package.extras] +dev = ["flake8", "mypy", "pycodestyle", "typing_extensions"] +doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-panels (>=0.5.2)", "sphinx-tabs"] +test = ["asv", "gmpy2", "mpmath", "pytest", "pytest-cov", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] + +[[package]] +name = "setuptools" +version = "65.5.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mock", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "setuptools-scm" +version = "7.0.5" +description = "the blessed package to manage your versions by scm tags" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +packaging = ">=20.0" +setuptools = "*" +tomli = ">=1.0.0" +typing-extensions = "*" + +[package.extras] +test = ["pytest (>=6.2)", "virtualenv (>20)"] +toml = ["setuptools (>=42)"] + +[[package]] +name = "sgp4" +version = "2.21" +description = "Track Earth satellites given TLE data, using up-to-date 2020 SGP4 routines." +category = "main" +optional = false +python-versions = "*" [[package]] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "skyfield" +version = "1.45" +description = "Elegant astronomy for Python" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +certifi = ">=2017.4.17" +jplephem = ">=2.13" +numpy = "*" +sgp4 = ">=2.2" + [[package]] name = "snowballstemmer" version = "2.2.0" @@ -466,7 +700,7 @@ optional = false python-versions = "*" [[package]] -name = "sphinx" +name = "Sphinx" version = "5.3.0" description = "Python documentation generator" category = "dev" @@ -606,21 +840,21 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" [[package]] name = "tomlkit" -version = "0.11.5" +version = "0.11.6" description = "Style preserving TOML library" category = "dev" optional = false -python-versions = ">=3.6,<4.0" +python-versions = ">=3.6" [[package]] name = "tox" -version = "3.26.0" +version = "3.27.0" description = "tox is a generic virtualenv management and test command line tool" category = "dev" optional = false @@ -841,7 +1075,7 @@ python-versions = "*" [[package]] name = "types-colorama" -version = "0.4.15.1" +version = "0.4.15.2" description = "Typing stubs for colorama" category = "dev" optional = false @@ -888,7 +1122,7 @@ optional = false python-versions = "*" [[package]] -name = "types-datetimerange" +name = "types-DateTimeRange" version = "1.2.8" description = "Typing stubs for DateTimeRange" category = "dev" @@ -907,7 +1141,7 @@ optional = false python-versions = "*" [[package]] -name = "types-deprecated" +name = "types-Deprecated" version = "1.2.9" description = "Typing stubs for Deprecated" category = "dev" @@ -971,7 +1205,7 @@ optional = false python-versions = "*" [[package]] -name = "types-flask" +name = "types-Flask" version = "1.1.6" description = "Typing stubs for Flask" category = "dev" @@ -1035,7 +1269,7 @@ optional = false python-versions = "*" [[package]] -name = "types-jack-client" +name = "types-JACK-Client" version = "0.5.10" description = "Typing stubs for JACK-Client" category = "dev" @@ -1043,7 +1277,7 @@ optional = false python-versions = "*" [[package]] -name = "types-jinja2" +name = "types-Jinja2" version = "2.11.9" description = "Typing stubs for Jinja2" category = "dev" @@ -1062,7 +1296,7 @@ optional = false python-versions = "*" [[package]] -name = "types-markdown" +name = "types-Markdown" version = "3.4.2.1" description = "Typing stubs for Markdown" category = "dev" @@ -1070,7 +1304,7 @@ optional = false python-versions = "*" [[package]] -name = "types-markupsafe" +name = "types-MarkupSafe" version = "1.1.10" description = "Typing stubs for MarkupSafe" category = "dev" @@ -1151,7 +1385,7 @@ optional = false python-versions = "*" [[package]] -name = "types-pillow" +name = "types-Pillow" version = "9.2.2.2" description = "Typing stubs for Pillow" category = "dev" @@ -1176,7 +1410,7 @@ python-versions = "*" [[package]] name = "types-protobuf" -version = "3.20.4.1" +version = "3.20.4.2" description = "Typing stubs for protobuf" category = "dev" optional = false @@ -1207,7 +1441,7 @@ optional = false python-versions = "*" [[package]] -name = "types-pyjwt" +name = "types-PyJWT" version = "1.7.1" description = "Typing stubs for PyJWT" category = "dev" @@ -1226,7 +1460,7 @@ optional = false python-versions = "*" [[package]] -name = "types-pymysql" +name = "types-PyMySQL" version = "1.0.19.1" description = "Typing stubs for PyMySQL" category = "dev" @@ -1234,7 +1468,7 @@ optional = false python-versions = "*" [[package]] -name = "types-pyrfc3339" +name = "types-pyRFC3339" version = "1.1.1" description = "Typing stubs for pyRFC3339" category = "dev" @@ -1293,8 +1527,8 @@ optional = false python-versions = "*" [[package]] -name = "types-pyyaml" -version = "6.0.12" +name = "types-PyYAML" +version = "6.0.12.1" description = "Typing stubs for PyYAML" category = "dev" optional = false @@ -1328,7 +1562,7 @@ optional = false python-versions = "*" [[package]] -name = "types-routes" +name = "types-Routes" version = "2.5.0" description = "Typing stubs for Routes" category = "dev" @@ -1404,7 +1638,7 @@ python-versions = "*" [[package]] name = "types-typed-ast" -version = "1.5.8" +version = "1.5.8.1" description = "Typing stubs for typed-ast" category = "dev" optional = false @@ -1446,7 +1680,7 @@ optional = false python-versions = "*" [[package]] -name = "types-werkzeug" +name = "types-Werkzeug" version = "1.0.9" description = "Typing stubs for Werkzeug" category = "dev" @@ -1465,7 +1699,7 @@ python-versions = "*" name = "typing-extensions" version = "4.4.0" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" @@ -1484,19 +1718,19 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "virtualenv" -version = "20.16.5" +version = "20.16.6" description = "Virtual Python Environment builder" category = "dev" optional = false python-versions = ">=3.6" [package.dependencies] -distlib = ">=0.3.5,<1" +distlib = ">=0.3.6,<1" filelock = ">=3.4.1,<4" platformdirs = ">=2.4,<3" [package.extras] -docs = ["proselint (>=0.13)", "sphinx (>=5.1.1)", "sphinx-argparse (>=0.3.1)", "sphinx-rtd-theme (>=1)", "towncrier (>=21.9)"] +docs = ["proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-argparse (>=0.3.2)", "sphinx-rtd-theme (>=1)", "towncrier (>=22.8)"] testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=21.3)", "pytest (>=7.0.1)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.6.1)", "pytest-randomly (>=3.10.3)", "pytest-timeout (>=2.1)"] [[package]] @@ -1507,6 +1741,27 @@ category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +[[package]] +name = "xarray" +version = "2022.10.0" +description = "N-D labeled arrays and datasets in Python" +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +numpy = ">=1.20" +packaging = ">=21.0" +pandas = ">=1.3" + +[package.extras] +accel = ["bottleneck", "flox", "numbagg", "scipy"] +complete = ["bottleneck", "cfgrib", "cftime", "dask[complete]", "flox", "fsspec", "h5netcdf", "matplotlib", "nc-time-axis", "netCDF4", "numbagg", "pooch", "pydap", "rasterio", "scipy", "seaborn", "zarr"] +docs = ["bottleneck", "cfgrib", "cftime", "dask[complete]", "flox", "fsspec", "h5netcdf", "ipykernel", "ipython", "jupyter-client", "matplotlib", "nbsphinx", "nc-time-axis", "netCDF4", "numbagg", "pooch", "pydap", "rasterio", "scanpydoc", "scipy", "seaborn", "sphinx-autosummary-accessors", "sphinx-rtd-theme", "zarr"] +io = ["cfgrib", "cftime", "fsspec", "h5netcdf", "netCDF4", "pooch", "pydap", "rasterio", "scipy", "zarr"] +parallel = ["dask[complete]"] +viz = ["matplotlib", "nc-time-axis", "seaborn"] + [[package]] name = "zipp" version = "3.10.0" @@ -1522,7 +1777,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "dbe578d1f8d4ca7f170698cb4dc4a74d37181d10ec4cc2fdc3d7433f9fb3c5ce" +content-hash = "a4e2c5046b1e922d328c2fbe33be99ba24f856a13c51a182fee1359e4be71283" [metadata.files] alabaster = [ @@ -1537,7 +1792,7 @@ attrs = [ {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, ] -babel = [ +Babel = [ {file = "Babel-2.10.3-py3-none-any.whl", hash = "sha256:ff56f4892c1c4bf0d814575ea23471c230d544203c7748e8c68f0089478d48eb"}, {file = "Babel-2.10.3.tar.gz", hash = "sha256:7614553711ee97490f732126dc077f8d0ae084ebc6a96e23db1482afabdb2c51"}, ] @@ -1577,8 +1832,79 @@ click = [ {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, ] colorama = [ - {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, - {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] +contourpy = [ + {file = "contourpy-1.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:87121b9428ac568fb84fae4af5e7852fc34f02eadc4e3e91f6c8989327692186"}, + {file = "contourpy-1.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1fb782982c42cee667b892a0b0c52a9f6c7ecf1da5c5f4345845f04eaa862f93"}, + {file = "contourpy-1.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:689d7d2a840619915d0abd1ecc6e399fee202f8ad315acda2807f4ca420d0802"}, + {file = "contourpy-1.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d88814befbd1433152c5f6dd536905149ba028d795a22555b149ae0a36024d9e"}, + {file = "contourpy-1.0.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df65f4b2b4e74977f0336bef12a88051ab24e6a16873cd9249f34d67cb3e345d"}, + {file = "contourpy-1.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf6b4c0c723664f65c2a47c8cb6ebbf660b0b2e2d936adf2e8503d4e93359465"}, + {file = "contourpy-1.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bcc98d397c3dea45d5b262029564b29cb8e945f2607a38bee6163694c0a8b4ef"}, + {file = "contourpy-1.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:2bf5c846c257578b03d498b20f54f53551616a507d8e5463511c58bb58e9a9cf"}, + {file = "contourpy-1.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdacddb18d55ffec42d1907079cdc04ec4fa8a990cdf5b9d9fe67d281fc0d12e"}, + {file = "contourpy-1.0.5-cp310-cp310-win32.whl", hash = "sha256:434942fa2f9019b9ae525fb752dc523800c49a1a28fbd6d9240b0fa959573dcc"}, + {file = "contourpy-1.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:3b3082ade8849130203d461b98c2a061b382c46074b43b4edd5cefd81af92b8a"}, + {file = "contourpy-1.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:057114f698ffb9e54657e8fda6802e2f5c8fad609845cf6afaf31590ef6a33c0"}, + {file = "contourpy-1.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:218722a29c5c26677d37c44f5f8a372daf6f07870aad793a97d47eb6ad6b3290"}, + {file = "contourpy-1.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6c02e22cf09996194bcb3a4784099975cf527d5c29caf759abadf29ebdb2fe27"}, + {file = "contourpy-1.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0d5ee865b5fd16bf62d72122aadcc90aab296c30c1adb0a32b4b66bd843163e"}, + {file = "contourpy-1.0.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45822b0a2a452327ab4f95efe368d234d5294bbf89a99968be27c7938a21108"}, + {file = "contourpy-1.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dca5be83a6dfaf933a46e3bc2b9f2685e5ec61b22f6a38ad740aac9c16e9a0ff"}, + {file = "contourpy-1.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3c3f2f6b898a40207843ae01970e57e33d22a26b22f23c6a5e07b4716751085f"}, + {file = "contourpy-1.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c2b4eab7c12f9cb460509bc34a3b086f9802f0dba27c89a63df4123819ad64af"}, + {file = "contourpy-1.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09ed9b63f4df8a7591b7a4a26c1ad066dcaafda1f846250fdcb534074a411692"}, + {file = "contourpy-1.0.5-cp311-cp311-win32.whl", hash = "sha256:f670686d99c867d0f24b28ce8c6f02429c6eef5e2674aab287850d0ee2d20437"}, + {file = "contourpy-1.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:c51568e94f7f232296de30002f2a50f77a7bd346673da3e4f2aaf9d2b833f2e5"}, + {file = "contourpy-1.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7c9e99aac7b430f6a9f15eebf058c742097cea3369f23a2bfc5e64d374b67e3a"}, + {file = "contourpy-1.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3210d93ad2af742b6a96cf39792f7181822edbb8fe11c3ef29d1583fe637a8d8"}, + {file = "contourpy-1.0.5-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:128bd7acf569f8443ad5b2227f30ac909e4f5399ed221727eeacf0c6476187e6"}, + {file = "contourpy-1.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:813c2944e940ef8dccea71305bacc942d4b193a021140874b3e58933ec44f5b6"}, + {file = "contourpy-1.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a74afd8d560eaafe0d9e3e1db8c06081282a05ca4de00ee416195085a79d7d3d"}, + {file = "contourpy-1.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d0ad9a85f208473b1f3613c45756c7aa6fcc288266a8c7b873f896aaf741b6b"}, + {file = "contourpy-1.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:60f37acd4e4227c5a29f737d9a85ca3145c529a8dd4bf70af7f0637c61b49222"}, + {file = "contourpy-1.0.5-cp37-cp37m-win32.whl", hash = "sha256:b50e481a4317a8efcfffcfddcd4c9b36eacba440440e70cbe0256aeb6fd6abae"}, + {file = "contourpy-1.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:0395ae71164bfeb2dedd136e03c71a2718a5aa9873a46f518f4133be0d63e1d2"}, + {file = "contourpy-1.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3ca40d7844b391d90b864c6a6d1bb6b88b09035fb4d866d64d43c4d26fb0ab64"}, + {file = "contourpy-1.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3109fa601d2a448cec4643abd3a31f972bf05b7c2f2e83df9d3429878f8c10ae"}, + {file = "contourpy-1.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:06c4d1dde5ee4f909a8a95ba1eb04040c6c26946b4f3b5beaf10d45f14e940ee"}, + {file = "contourpy-1.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f54dcc9bb9390fd0636301ead134d46d5229fe86da0db4d974c0fda349f560e"}, + {file = "contourpy-1.0.5-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:46b8e24813e2fb5a3e598c1f8b9ae403e1438cb846a80cc2b33cddf19dddd7f2"}, + {file = "contourpy-1.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:061e1f066c419ffe25b615a1df031b4832ea1d7f2676937e69e8e00e24512005"}, + {file = "contourpy-1.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:19ea64fa0cf389d2ebc10974616acfa1fdecbd73d1fd9c72215b782f3c40f561"}, + {file = "contourpy-1.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dfe924e5a63861c82332a12adeeab955dc8c8009ddbbd80cc2fcca049ff89a49"}, + {file = "contourpy-1.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bed3a2a823a041e8d249b1a7ec132933e1505299329b5cfe1b2b5ec689ec7675"}, + {file = "contourpy-1.0.5-cp38-cp38-win32.whl", hash = "sha256:0389349875424aa8c5e61f757e894687916bc4e9616cc6afcbd8051aa2428952"}, + {file = "contourpy-1.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:2b5e334330d82866923015b455260173cb3b9e3b4e297052d758abd262031289"}, + {file = "contourpy-1.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:def9a01b73c9e27d70ea03b381fb3e7aadfac1f398dbd63751313c3a46747ef5"}, + {file = "contourpy-1.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:59c827e536bb5e3ef58e06da0faba61fd89a14f30b68bcfeca41f43ca83a1942"}, + {file = "contourpy-1.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f05d311c937da03b0cd26ac3e14cb991f6ff8fc94f98b3df9713537817539795"}, + {file = "contourpy-1.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:970a4be7ec84ccda7c27cb4ae74930bbbd477bc8d849ed55ea798084dd5fca8c"}, + {file = "contourpy-1.0.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f7672148f8fca48e4efc16aba24a7455b40c22d4f8abe42475dec6a12b0bb9a"}, + {file = "contourpy-1.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eba62b7c21a33e72dd8adab2b92dd5610d8527f0b2ac28a8e0770e71b21a13f9"}, + {file = "contourpy-1.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:dd084459ecdb224e617e4ab3f1d5ebe4d1c48facb41f24952b76aa6ba9712bb0"}, + {file = "contourpy-1.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c5158616ab39d34b76c50f40c81552ee180598f7825dc7a66fd187d29958820f"}, + {file = "contourpy-1.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f856652f9b533c6cd2b9ad6836a7fc0e43917d7ff15be46c5baf1350f8cdc5d9"}, + {file = "contourpy-1.0.5-cp39-cp39-win32.whl", hash = "sha256:f1cc623fd6855b25da52b3275e0c9e51711b86a9dccc75f8c9ab4432fd8e42c7"}, + {file = "contourpy-1.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:e67dcaa34dcd908fcccbf49194211d847c731b6ebaac661c1c889f1bf6af1e44"}, + {file = "contourpy-1.0.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bfd634cb9685161b2a51f73a7fc4736fd0d67a56632d52319317afaa27f08243"}, + {file = "contourpy-1.0.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79908b9d02b1d6c1c71ff3b7ad127f3f82e14a8e091ab44b3c7e34b649fea733"}, + {file = "contourpy-1.0.5-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4963cf08f4320d98ae72ec7694291b8ab85cb7da3b0cd824bc32701bc992edf"}, + {file = "contourpy-1.0.5-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cfc067ddde78b76dcbc9684d82688b7d3c5158fa2254a085f9bcb9586c1e2d8"}, + {file = "contourpy-1.0.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:9939796abcadb2810a63dfb26ff8ca4595fe7dd70a3ceae7f607a2639b714307"}, + {file = "contourpy-1.0.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d8150579bf30cdf896906baf256aa200cd50dbe6e565c17d6fd3d678e21ff5de"}, + {file = "contourpy-1.0.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed9c91bf4ce614efed5388c3f989a7cfe08728ab871d995a486ea74ff88993db"}, + {file = "contourpy-1.0.5-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b46a04588ceb7cf132568e0e564a854627ef87a1ed3bf536234540a79ced44b0"}, + {file = "contourpy-1.0.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b85553699862c09937a7a5ea14ee6229087971a7d51ae97d5f4b407f571a2c17"}, + {file = "contourpy-1.0.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:99a8071e351b50827ad976b92ed91845fb614ac67a3c41109b24f3d8bd3afada"}, + {file = "contourpy-1.0.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fb0458d74726937ead9e2effc91144aea5a58ecee9754242f8539a782bed685a"}, + {file = "contourpy-1.0.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f89f0608a5aa8142ed0e53957916623791a88c7f5e5f07ae530c328beeb888f"}, + {file = "contourpy-1.0.5-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce763369e646e59e4ca2c09735cd1bdd3048d909ad5f2bc116e83166a9352f3c"}, + {file = "contourpy-1.0.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c16fa267740d67883899e054cccb4279e002f3f4872873b752c1ba15045ff49"}, + {file = "contourpy-1.0.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a30e95274f5c0e007ccc759ec258aa5708c534ec058f153ee25ac700a2f1438b"}, + {file = "contourpy-1.0.5.tar.gz", hash = "sha256:896631cd40222aef3697e4e51177d14c3709fda49d30983269d584f034acc8a4"}, ] coverage = [ {file = "coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"}, @@ -1632,6 +1958,10 @@ coverage = [ {file = "coverage-6.5.0-pp36.pp37.pp38-none-any.whl", hash = "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a"}, {file = "coverage-6.5.0.tar.gz", hash = "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84"}, ] +cycler = [ + {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, + {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, +] dill = [ {file = "dill-0.3.6-py3-none-any.whl", hash = "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0"}, {file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"}, @@ -1644,14 +1974,25 @@ docutils = [ {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, ] +exceptiongroup = [ + {file = "exceptiongroup-1.0.0-py3-none-any.whl", hash = "sha256:2ac84b496be68464a2da60da518af3785fff8b7ec0d090a581604bc870bdee41"}, + {file = "exceptiongroup-1.0.0.tar.gz", hash = "sha256:affbabf13fb6e98988c38d9c5650e701569fe3c1de3233cfb61c5f33774690ad"}, +] filelock = [ {file = "filelock-3.8.0-py3-none-any.whl", hash = "sha256:617eb4e5eedc82fc5f47b6d61e4d11cb837c56cb4544e39081099fa17ad109d4"}, {file = "filelock-3.8.0.tar.gz", hash = "sha256:55447caa666f2198c5b6b13a26d2084d26fa5b115c00d065664b2124680c4edc"}, ] +fonttools = [ + {file = "fonttools-4.38.0-py3-none-any.whl", hash = "sha256:820466f43c8be8c3009aef8b87e785014133508f0de64ec469e4efb643ae54fb"}, + {file = "fonttools-4.38.0.zip", hash = "sha256:2bb244009f9bf3fa100fc3ead6aeb99febe5985fa20afbfbaa2f8946c2fbdaf1"}, +] idna = [ {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, ] +igrf = [ + {file = "igrf-13.0.2.tar.gz", hash = "sha256:867caa2c8dffe87b42f6187afb97a92e60c08c4e49ac5a57a46112e3121ca1a9"}, +] imagesize = [ {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, @@ -1668,50 +2009,106 @@ isort = [ {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, ] -jinja2 = [ +Jinja2 = [ {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, ] +jplephem = [ + {file = "jplephem-2.18-py3-none-any.whl", hash = "sha256:ecfbf13779650288b958bb1f3848d6445163b0e879ca96759c941841f55abf1c"}, + {file = "jplephem-2.18.tar.gz", hash = "sha256:492911e8a4c47830791b03b9a0ffdf7fc65f685d1cbb3a1790b1ea288ae7fae5"}, +] +kiwisolver = [ + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"}, + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"}, + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"}, + {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"}, + {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"}, + {file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"}, + {file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"}, + {file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"}, + {file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"}, + {file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"}, + {file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"}, + {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"}, +] lazy-object-proxy = [ - {file = "lazy-object-proxy-1.7.1.tar.gz", hash = "sha256:d609c75b986def706743cdebe5e47553f4a5a1da9c5ff66d76013ef396b5a8a4"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb8c5fd1684d60a9902c60ebe276da1f2281a318ca16c1d0a96db28f62e9166b"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a57d51ed2997e97f3b8e3500c984db50a554bb5db56c50b5dab1b41339b37e36"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd45683c3caddf83abbb1249b653a266e7069a09f486daa8863fb0e7496a9fdb"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8561da8b3dd22d696244d6d0d5330618c993a215070f473b699e00cf1f3f6443"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fccdf7c2c5821a8cbd0a9440a456f5050492f2270bd54e94360cac663398739b"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-win32.whl", hash = "sha256:898322f8d078f2654d275124a8dd19b079080ae977033b713f677afcfc88e2b9"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:85b232e791f2229a4f55840ed54706110c80c0a210d076eee093f2b2e33e1bfd"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:46ff647e76f106bb444b4533bb4153c7370cdf52efc62ccfc1a28bdb3cc95442"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12f3bb77efe1367b2515f8cb4790a11cffae889148ad33adad07b9b55e0ab22c"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c19814163728941bb871240d45c4c30d33b8a2e85972c44d4e63dd7107faba44"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:e40f2013d96d30217a51eeb1db28c9ac41e9d0ee915ef9d00da639c5b63f01a1"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:2052837718516a94940867e16b1bb10edb069ab475c3ad84fd1e1a6dd2c0fcfc"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win32.whl", hash = "sha256:6a24357267aa976abab660b1d47a34aaf07259a0c3859a34e536f1ee6e76b5bb"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:6aff3fe5de0831867092e017cf67e2750c6a1c7d88d84d2481bd84a2e019ec35"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6a6e94c7b02641d1311228a102607ecd576f70734dc3d5e22610111aeacba8a0"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ce15276a1a14549d7e81c243b887293904ad2d94ad767f42df91e75fd7b5b6"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e368b7f7eac182a59ff1f81d5f3802161932a41dc1b1cc45c1f757dc876b5d2c"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6ecbb350991d6434e1388bee761ece3260e5228952b1f0c46ffc800eb313ff42"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:553b0f0d8dbf21890dd66edd771f9b1b5f51bd912fa5f26de4449bfc5af5e029"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win32.whl", hash = "sha256:c7a683c37a8a24f6428c28c561c80d5f4fd316ddcf0c7cab999b15ab3f5c5c69"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:df2631f9d67259dc9620d831384ed7732a198eb434eadf69aea95ad18c587a28"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:07fa44286cda977bd4803b656ffc1c9b7e3bc7dff7d34263446aec8f8c96f88a"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dca6244e4121c74cc20542c2ca39e5c4a5027c81d112bfb893cf0790f96f57e"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91ba172fc5b03978764d1df5144b4ba4ab13290d7bab7a50f12d8117f8630c38"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:043651b6cb706eee4f91854da4a089816a6606c1428fd391573ef8cb642ae4f7"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b9e89b87c707dd769c4ea91f7a31538888aad05c116a59820f28d59b3ebfe25a"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-win32.whl", hash = "sha256:9d166602b525bf54ac994cf833c385bfcc341b364e3ee71e3bf5a1336e677b55"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:8f3953eb575b45480db6568306893f0bd9d8dfeeebd46812aa09ca9579595148"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dd7ed7429dbb6c494aa9bc4e09d94b778a3579be699f9d67da7e6804c422d3de"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70ed0c2b380eb6248abdef3cd425fc52f0abd92d2b07ce26359fcbc399f636ad"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7096a5e0c1115ec82641afbdd70451a144558ea5cf564a896294e346eb611be1"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f769457a639403073968d118bc70110e7dce294688009f5c24ab78800ae56dc8"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:39b0e26725c5023757fc1ab2a89ef9d7ab23b84f9251e28f9cc114d5b59c1b09"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-win32.whl", hash = "sha256:2130db8ed69a48a3440103d4a520b89d8a9405f1b06e2cc81640509e8bf6548f"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61"}, - {file = "lazy_object_proxy-1.7.1-pp37.pp38-none-any.whl", hash = "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84"}, -] -markupsafe = [ + {file = "lazy-object-proxy-1.8.0.tar.gz", hash = "sha256:c219a00245af0f6fa4e95901ed28044544f50152840c5b6a3e7b2568db34d156"}, + {file = "lazy_object_proxy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4fd031589121ad46e293629b39604031d354043bb5cdf83da4e93c2d7f3389fe"}, + {file = "lazy_object_proxy-1.8.0-cp310-cp310-win32.whl", hash = "sha256:b70d6e7a332eb0217e7872a73926ad4fdc14f846e85ad6749ad111084e76df25"}, + {file = "lazy_object_proxy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:eb329f8d8145379bf5dbe722182410fe8863d186e51bf034d2075eb8d85ee25b"}, + {file = "lazy_object_proxy-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4e2d9f764f1befd8bdc97673261b8bb888764dfdbd7a4d8f55e4fbcabb8c3fb7"}, + {file = "lazy_object_proxy-1.8.0-cp311-cp311-win32.whl", hash = "sha256:e20bfa6db17a39c706d24f82df8352488d2943a3b7ce7d4c22579cb89ca8896e"}, + {file = "lazy_object_proxy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:14010b49a2f56ec4943b6cf925f597b534ee2fe1f0738c84b3bce0c1a11ff10d"}, + {file = "lazy_object_proxy-1.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6850e4aeca6d0df35bb06e05c8b934ff7c533734eb51d0ceb2d63696f1e6030c"}, + {file = "lazy_object_proxy-1.8.0-cp37-cp37m-win32.whl", hash = "sha256:5b51d6f3bfeb289dfd4e95de2ecd464cd51982fe6f00e2be1d0bf94864d58acd"}, + {file = "lazy_object_proxy-1.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:6f593f26c470a379cf7f5bc6db6b5f1722353e7bf937b8d0d0b3fba911998858"}, + {file = "lazy_object_proxy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c1c7c0433154bb7c54185714c6929acc0ba04ee1b167314a779b9025517eada"}, + {file = "lazy_object_proxy-1.8.0-cp38-cp38-win32.whl", hash = "sha256:d176f392dbbdaacccf15919c77f526edf11a34aece58b55ab58539807b85436f"}, + {file = "lazy_object_proxy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:afcaa24e48bb23b3be31e329deb3f1858f1f1df86aea3d70cb5c8578bfe5261c"}, + {file = "lazy_object_proxy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:71d9ae8a82203511a6f60ca5a1b9f8ad201cac0fc75038b2dc5fa519589c9288"}, + {file = "lazy_object_proxy-1.8.0-cp39-cp39-win32.whl", hash = "sha256:8f6ce2118a90efa7f62dd38c7dbfffd42f468b180287b748626293bf12ed468f"}, + {file = "lazy_object_proxy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:eac3a9a5ef13b332c059772fd40b4b1c3d45a3a2b05e33a361dee48e54a4dad0"}, + {file = "lazy_object_proxy-1.8.0-pp37-pypy37_pp73-any.whl", hash = "sha256:ae032743794fba4d171b5b67310d69176287b5bf82a21f588282406a79498891"}, + {file = "lazy_object_proxy-1.8.0-pp38-pypy38_pp73-any.whl", hash = "sha256:7e1561626c49cb394268edd00501b289053a652ed762c58e1081224c8d881cec"}, + {file = "lazy_object_proxy-1.8.0-pp39-pypy39_pp73-any.whl", hash = "sha256:ce58b2b3734c73e68f0e30e4e725264d4d6be95818ec0a0be4bb6bf9a7e79aa8"}, +] +MarkupSafe = [ {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, @@ -1753,6 +2150,49 @@ markupsafe = [ {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, ] +matplotlib = [ + {file = "matplotlib-3.6.1-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:7730e60e751cfcfe7fcb223cf03c0b979e9a064c239783ad37929d340a364cef"}, + {file = "matplotlib-3.6.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9dd40505ccc526acaf9a5db1b3029e237c64b58f1249983b28a291c2d6a1d0fa"}, + {file = "matplotlib-3.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:85948b303534b69fd771126764cf883fde2af9b003eb5778cb60f3b46f93d3f6"}, + {file = "matplotlib-3.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71eced071825005011cdc64efbae2e2c76b8209c18aa487dedf69796fe4b1e40"}, + {file = "matplotlib-3.6.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:220314c2d6b9ca11570d7cd4b841c9f3137546f188336003b9fb8def4dcb804d"}, + {file = "matplotlib-3.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2cc5d726d4d42865f909c5208a7841109d76584950dd0587b01a77cc279d4ab7"}, + {file = "matplotlib-3.6.1-cp310-cp310-win32.whl", hash = "sha256:183bf3ac6a6023ee590aa4b677f391ceed65ec0d6b930901a8483c267bd12995"}, + {file = "matplotlib-3.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:a68b91ac7e6bb26100a540a033f54c95fe06d9c0aa51312c2a52d07d1bde78f4"}, + {file = "matplotlib-3.6.1-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:4648f0d79a87bf50ee740058305c91091ee5e1fbb71a7d2f5fe6707bfe328d1c"}, + {file = "matplotlib-3.6.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:9403764017d20ff570f7ce973a8b9637f08a6109118f4e0ce6c7493d8849a0d3"}, + {file = "matplotlib-3.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4c8b5a243dd29d50289d694e931bd6cb6ae0b5bd654d12c647543d63862540c"}, + {file = "matplotlib-3.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1effccef0cea2d4da9feeed22079adf6786f92c800a7d0d2ef2104318a1c66c"}, + {file = "matplotlib-3.6.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dc25473319afabe49150267e54648ac559c33b0fc2a80c8caecfbbc2948a820"}, + {file = "matplotlib-3.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47cb088bbce82ae9fc2edf3c25e56a5c6142ce2553fea2b781679f960a70c207"}, + {file = "matplotlib-3.6.1-cp311-cp311-win32.whl", hash = "sha256:4d3b0e0a4611bd22065bbf47e9b2f689ac9e575bcb850a9f0ae2bbed75cab956"}, + {file = "matplotlib-3.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:e3c116e779fbbf421a9e4d3060db259a9bb486d98f4e3c5a0877c599bd173582"}, + {file = "matplotlib-3.6.1-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:565f514dec81a41cbed10eb6011501879695087fc2787fb89423a466508abbbd"}, + {file = "matplotlib-3.6.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:05e86446562063d6186ff6d700118c0dbd5dccc403a6187351ee526c48878f10"}, + {file = "matplotlib-3.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8245e85fd793f58edf29b8a9e3be47e8ecf76ea1a1e8240545f2746181ca5787"}, + {file = "matplotlib-3.6.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1e2c75d5d1ff6b7ef9870360bfa23bea076b8dc0945a60d19453d7619ed9ea8f"}, + {file = "matplotlib-3.6.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c9756a8e69f6e1f76d47eb42132175b6814da1fbeae0545304c6d0fc2aae252a"}, + {file = "matplotlib-3.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f5788168da2661b42f7468063b725cc73fdbeeb80f2704cb2d8c415e9a57c50"}, + {file = "matplotlib-3.6.1-cp38-cp38-win32.whl", hash = "sha256:0bab7564aafd5902128d54b68dca04f5755413fb6b502100bb0235a545882c48"}, + {file = "matplotlib-3.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3c53486278a0629fd892783271dc994b962fba8dfe207445d039e14f1928ea46"}, + {file = "matplotlib-3.6.1-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:27337bcb38d5db7430c14f350924542d75416ec1546d5d9d9f39b362b71db3fb"}, + {file = "matplotlib-3.6.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:fad858519bd6d52dbfeebdbe04d00dd8e932ed436f1c535e61bcc970a96c11e4"}, + {file = "matplotlib-3.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4a3d903588b519b38ed085d0ae762a1dcd4b70164617292175cfd91b90d6c415"}, + {file = "matplotlib-3.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87bdbd37d0a41e025879863fe9b17bab15c0421313bc33e77e5e1aa54215c9c5"}, + {file = "matplotlib-3.6.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e632f66218811d4cf8b7a2a649e25ec15406c3c498f72d19e2bcf8377f38445d"}, + {file = "matplotlib-3.6.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ddd58324dc9a77e2e56d7b7aea7dbd0575b6f7cd1333c3ca9d388ac70978344"}, + {file = "matplotlib-3.6.1-cp39-cp39-win32.whl", hash = "sha256:12ab21d0cad122f5b23688d453a0280676e7c42f634f0dbd093d15d42d142b1f"}, + {file = "matplotlib-3.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:563896ba269324872ace436a57775dcc8322678a9496b28a8c25cdafa5ec2b92"}, + {file = "matplotlib-3.6.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:52935b7d4ccbf0dbc9cf454dbb10ca99c11cbe8da9467596b96e5e21fd4dfc5c"}, + {file = "matplotlib-3.6.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87027ff7b2edeb14476900261ef04d4beae949e1dfa0a3eb3ad6a6efbf9d0e1d"}, + {file = "matplotlib-3.6.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4de03085afb3b80fab341afaf8e60dfe06ce439b6dfed55d657cf34a7bc3c40"}, + {file = "matplotlib-3.6.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b53387d4e59432ff221540a4ffb5ee9669c69417805e4faf0148a00d701c61f9"}, + {file = "matplotlib-3.6.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:02561141c434154f7bae8e5449909d152367cb40aa57bfb2a27f2748b9c5f95f"}, + {file = "matplotlib-3.6.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0161ebf87518ecfe0980c942d5f0d5df0e080c1746ebaab2027a969967014b7"}, + {file = "matplotlib-3.6.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2469f57e4c5cc0e85eddc7b30995ea9c404a78c0b1856da75d1a5887156ca350"}, + {file = "matplotlib-3.6.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:5f97141e05baf160c3ec125f06ceb2a44c9bb62f42fcb8ee1c05313c73e99432"}, + {file = "matplotlib-3.6.1.tar.gz", hash = "sha256:e2d1b7225666f7e1bcc94c0bc9c587a82e3e8691da4757e357e5c2515222ee37"}, +] mccabe = [ {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, @@ -1787,14 +2227,134 @@ mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] +numpy = [ + {file = "numpy-1.23.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:95d79ada05005f6f4f337d3bb9de8a7774f259341c70bc88047a1f7b96a4bcb2"}, + {file = "numpy-1.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:926db372bc4ac1edf81cfb6c59e2a881606b409ddc0d0920b988174b2e2a767f"}, + {file = "numpy-1.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c237129f0e732885c9a6076a537e974160482eab8f10db6292e92154d4c67d71"}, + {file = "numpy-1.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8365b942f9c1a7d0f0dc974747d99dd0a0cdfc5949a33119caf05cb314682d3"}, + {file = "numpy-1.23.4-cp310-cp310-win32.whl", hash = "sha256:2341f4ab6dba0834b685cce16dad5f9b6606ea8a00e6da154f5dbded70fdc4dd"}, + {file = "numpy-1.23.4-cp310-cp310-win_amd64.whl", hash = "sha256:d331afac87c92373826af83d2b2b435f57b17a5c74e6268b79355b970626e329"}, + {file = "numpy-1.23.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:488a66cb667359534bc70028d653ba1cf307bae88eab5929cd707c761ff037db"}, + {file = "numpy-1.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ce03305dd694c4873b9429274fd41fc7eb4e0e4dea07e0af97a933b079a5814f"}, + {file = "numpy-1.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8981d9b5619569899666170c7c9748920f4a5005bf79c72c07d08c8a035757b0"}, + {file = "numpy-1.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a70a7d3ce4c0e9284e92285cba91a4a3f5214d87ee0e95928f3614a256a1488"}, + {file = "numpy-1.23.4-cp311-cp311-win32.whl", hash = "sha256:5e13030f8793e9ee42f9c7d5777465a560eb78fa7e11b1c053427f2ccab90c79"}, + {file = "numpy-1.23.4-cp311-cp311-win_amd64.whl", hash = "sha256:7607b598217745cc40f751da38ffd03512d33ec06f3523fb0b5f82e09f6f676d"}, + {file = "numpy-1.23.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7ab46e4e7ec63c8a5e6dbf5c1b9e1c92ba23a7ebecc86c336cb7bf3bd2fb10e5"}, + {file = "numpy-1.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8aae2fb3180940011b4862b2dd3756616841c53db9734b27bb93813cd79fce6"}, + {file = "numpy-1.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c053d7557a8f022ec823196d242464b6955a7e7e5015b719e76003f63f82d0f"}, + {file = "numpy-1.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0882323e0ca4245eb0a3d0a74f88ce581cc33aedcfa396e415e5bba7bf05f68"}, + {file = "numpy-1.23.4-cp38-cp38-win32.whl", hash = "sha256:dada341ebb79619fe00a291185bba370c9803b1e1d7051610e01ed809ef3a4ba"}, + {file = "numpy-1.23.4-cp38-cp38-win_amd64.whl", hash = "sha256:0fe563fc8ed9dc4474cbf70742673fc4391d70f4363f917599a7fa99f042d5a8"}, + {file = "numpy-1.23.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c67b833dbccefe97cdd3f52798d430b9d3430396af7cdb2a0c32954c3ef73894"}, + {file = "numpy-1.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f76025acc8e2114bb664294a07ede0727aa75d63a06d2fae96bf29a81747e4a7"}, + {file = "numpy-1.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12ac457b63ec8ded85d85c1e17d85efd3c2b0967ca39560b307a35a6703a4735"}, + {file = "numpy-1.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95de7dc7dc47a312f6feddd3da2500826defdccbc41608d0031276a24181a2c0"}, + {file = "numpy-1.23.4-cp39-cp39-win32.whl", hash = "sha256:f2f390aa4da44454db40a1f0201401f9036e8d578a25f01a6e237cea238337ef"}, + {file = "numpy-1.23.4-cp39-cp39-win_amd64.whl", hash = "sha256:f260da502d7441a45695199b4e7fd8ca87db659ba1c78f2bbf31f934fe76ae0e"}, + {file = "numpy-1.23.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:61be02e3bf810b60ab74e81d6d0d36246dbfb644a462458bb53b595791251911"}, + {file = "numpy-1.23.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:296d17aed51161dbad3c67ed6d164e51fcd18dbcd5dd4f9d0a9c6055dce30810"}, + {file = "numpy-1.23.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4d52914c88b4930dafb6c48ba5115a96cbab40f45740239d9f4159c4ba779962"}, + {file = "numpy-1.23.4.tar.gz", hash = "sha256:ed2cc92af0efad20198638c69bb0fc2870a58dabfba6eb722c933b48556c686c"}, +] packaging = [ {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] +pandas = [ + {file = "pandas-1.5.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0a78e05ec09731c5b3bd7a9805927ea631fe6f6cb06f0e7c63191a9a778d52b4"}, + {file = "pandas-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5b0c970e2215572197b42f1cff58a908d734503ea54b326412c70d4692256391"}, + {file = "pandas-1.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f340331a3f411910adfb4bbe46c2ed5872d9e473a783d7f14ecf49bc0869c594"}, + {file = "pandas-1.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8c709f4700573deb2036d240d140934df7e852520f4a584b2a8d5443b71f54d"}, + {file = "pandas-1.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32e3d9f65606b3f6e76555bfd1d0b68d94aff0929d82010b791b6254bf5a4b96"}, + {file = "pandas-1.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:a52419d9ba5906db516109660b114faf791136c94c1a636ed6b29cbfff9187ee"}, + {file = "pandas-1.5.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:66a1ad667b56e679e06ba73bb88c7309b3f48a4c279bd3afea29f65a766e9036"}, + {file = "pandas-1.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:36aa1f8f680d7584e9b572c3203b20d22d697c31b71189322f16811d4ecfecd3"}, + {file = "pandas-1.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bcf1a82b770b8f8c1e495b19a20d8296f875a796c4fe6e91da5ef107f18c5ecb"}, + {file = "pandas-1.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c25e5c16ee5c0feb6cf9d982b869eec94a22ddfda9aa2fbed00842cbb697624"}, + {file = "pandas-1.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:932d2d7d3cab44cfa275601c982f30c2d874722ef6396bb539e41e4dc4618ed4"}, + {file = "pandas-1.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:eb7e8cf2cf11a2580088009b43de84cabbf6f5dae94ceb489f28dba01a17cb77"}, + {file = "pandas-1.5.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:cb2a9cf1150302d69bb99861c5cddc9c25aceacb0a4ef5299785d0f5389a3209"}, + {file = "pandas-1.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:81f0674fa50b38b6793cd84fae5d67f58f74c2d974d2cb4e476d26eee33343d0"}, + {file = "pandas-1.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:17da7035d9e6f9ea9cdc3a513161f8739b8f8489d31dc932bc5a29a27243f93d"}, + {file = "pandas-1.5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:669c8605dba6c798c1863157aefde959c1796671ffb342b80fcb80a4c0bc4c26"}, + {file = "pandas-1.5.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:683779e5728ac9138406c59a11e09cd98c7d2c12f0a5fc2b9c5eecdbb4a00075"}, + {file = "pandas-1.5.1-cp38-cp38-win32.whl", hash = "sha256:ddf46b940ef815af4e542697eaf071f0531449407a7607dd731bf23d156e20a7"}, + {file = "pandas-1.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:db45b94885000981522fb92349e6b76f5aee0924cc5315881239c7859883117d"}, + {file = "pandas-1.5.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:927e59c694e039c75d7023465d311277a1fc29ed7236b5746e9dddf180393113"}, + {file = "pandas-1.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e675f8fe9aa6c418dc8d3aac0087b5294c1a4527f1eacf9fe5ea671685285454"}, + {file = "pandas-1.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:04e51b01d5192499390c0015630975f57836cc95c7411415b499b599b05c0c96"}, + {file = "pandas-1.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cee0c74e93ed4f9d39007e439debcaadc519d7ea5c0afc3d590a3a7b2edf060"}, + {file = "pandas-1.5.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b156a971bc451c68c9e1f97567c94fd44155f073e3bceb1b0d195fd98ed12048"}, + {file = "pandas-1.5.1-cp39-cp39-win32.whl", hash = "sha256:05c527c64ee02a47a24031c880ee0ded05af0623163494173204c5b72ddce658"}, + {file = "pandas-1.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:6bb391659a747cf4f181a227c3e64b6d197100d53da98dcd766cc158bdd9ec68"}, + {file = "pandas-1.5.1.tar.gz", hash = "sha256:249cec5f2a5b22096440bd85c33106b6102e0672204abd2d5c014106459804ee"}, +] pathspec = [ {file = "pathspec-0.10.1-py3-none-any.whl", hash = "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93"}, {file = "pathspec-0.10.1.tar.gz", hash = "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d"}, ] +Pillow = [ + {file = "Pillow-9.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:0b7257127d646ff8676ec8a15520013a698d1fdc48bc2a79ba4e53df792526f2"}, + {file = "Pillow-9.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b90f7616ea170e92820775ed47e136208e04c967271c9ef615b6fbd08d9af0e3"}, + {file = "Pillow-9.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68943d632f1f9e3dce98908e873b3a090f6cba1cbb1b892a9e8d97c938871fbe"}, + {file = "Pillow-9.3.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be55f8457cd1eac957af0c3f5ece7bc3f033f89b114ef30f710882717670b2a8"}, + {file = "Pillow-9.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d77adcd56a42d00cc1be30843d3426aa4e660cab4a61021dc84467123f7a00c"}, + {file = "Pillow-9.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:829f97c8e258593b9daa80638aee3789b7df9da5cf1336035016d76f03b8860c"}, + {file = "Pillow-9.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:801ec82e4188e935c7f5e22e006d01611d6b41661bba9fe45b60e7ac1a8f84de"}, + {file = "Pillow-9.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:871b72c3643e516db4ecf20efe735deb27fe30ca17800e661d769faab45a18d7"}, + {file = "Pillow-9.3.0-cp310-cp310-win32.whl", hash = "sha256:655a83b0058ba47c7c52e4e2df5ecf484c1b0b0349805896dd350cbc416bdd91"}, + {file = "Pillow-9.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:9f47eabcd2ded7698106b05c2c338672d16a6f2a485e74481f524e2a23c2794b"}, + {file = "Pillow-9.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:57751894f6618fd4308ed8e0c36c333e2f5469744c34729a27532b3db106ee20"}, + {file = "Pillow-9.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7db8b751ad307d7cf238f02101e8e36a128a6cb199326e867d1398067381bff4"}, + {file = "Pillow-9.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3033fbe1feb1b59394615a1cafaee85e49d01b51d54de0cbf6aa8e64182518a1"}, + {file = "Pillow-9.3.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22b012ea2d065fd163ca096f4e37e47cd8b59cf4b0fd47bfca6abb93df70b34c"}, + {file = "Pillow-9.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9a65733d103311331875c1dca05cb4606997fd33d6acfed695b1232ba1df193"}, + {file = "Pillow-9.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:502526a2cbfa431d9fc2a079bdd9061a2397b842bb6bc4239bb176da00993812"}, + {file = "Pillow-9.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:90fb88843d3902fe7c9586d439d1e8c05258f41da473952aa8b328d8b907498c"}, + {file = "Pillow-9.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:89dca0ce00a2b49024df6325925555d406b14aa3efc2f752dbb5940c52c56b11"}, + {file = "Pillow-9.3.0-cp311-cp311-win32.whl", hash = "sha256:3168434d303babf495d4ba58fc22d6604f6e2afb97adc6a423e917dab828939c"}, + {file = "Pillow-9.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:18498994b29e1cf86d505edcb7edbe814d133d2232d256db8c7a8ceb34d18cef"}, + {file = "Pillow-9.3.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:772a91fc0e03eaf922c63badeca75e91baa80fe2f5f87bdaed4280662aad25c9"}, + {file = "Pillow-9.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa4107d1b306cdf8953edde0534562607fe8811b6c4d9a486298ad31de733b2"}, + {file = "Pillow-9.3.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4012d06c846dc2b80651b120e2cdd787b013deb39c09f407727ba90015c684f"}, + {file = "Pillow-9.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77ec3e7be99629898c9a6d24a09de089fa5356ee408cdffffe62d67bb75fdd72"}, + {file = "Pillow-9.3.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:6c738585d7a9961d8c2821a1eb3dcb978d14e238be3d70f0a706f7fa9316946b"}, + {file = "Pillow-9.3.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:828989c45c245518065a110434246c44a56a8b2b2f6347d1409c787e6e4651ee"}, + {file = "Pillow-9.3.0-cp37-cp37m-win32.whl", hash = "sha256:82409ffe29d70fd733ff3c1025a602abb3e67405d41b9403b00b01debc4c9a29"}, + {file = "Pillow-9.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:41e0051336807468be450d52b8edd12ac60bebaa97fe10c8b660f116e50b30e4"}, + {file = "Pillow-9.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:b03ae6f1a1878233ac620c98f3459f79fd77c7e3c2b20d460284e1fb370557d4"}, + {file = "Pillow-9.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4390e9ce199fc1951fcfa65795f239a8a4944117b5935a9317fb320e7767b40f"}, + {file = "Pillow-9.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40e1ce476a7804b0fb74bcfa80b0a2206ea6a882938eaba917f7a0f004b42502"}, + {file = "Pillow-9.3.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0a06a052c5f37b4ed81c613a455a81f9a3a69429b4fd7bb913c3fa98abefc20"}, + {file = "Pillow-9.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03150abd92771742d4a8cd6f2fa6246d847dcd2e332a18d0c15cc75bf6703040"}, + {file = "Pillow-9.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:15c42fb9dea42465dfd902fb0ecf584b8848ceb28b41ee2b58f866411be33f07"}, + {file = "Pillow-9.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:51e0e543a33ed92db9f5ef69a0356e0b1a7a6b6a71b80df99f1d181ae5875636"}, + {file = "Pillow-9.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3dd6caf940756101205dffc5367babf288a30043d35f80936f9bfb37f8355b32"}, + {file = "Pillow-9.3.0-cp38-cp38-win32.whl", hash = "sha256:f1ff2ee69f10f13a9596480335f406dd1f70c3650349e2be67ca3139280cade0"}, + {file = "Pillow-9.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:276a5ca930c913f714e372b2591a22c4bd3b81a418c0f6635ba832daec1cbcfc"}, + {file = "Pillow-9.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:73bd195e43f3fadecfc50c682f5055ec32ee2c933243cafbfdec69ab1aa87cad"}, + {file = "Pillow-9.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c7c8ae3864846fc95f4611c78129301e203aaa2af813b703c55d10cc1628535"}, + {file = "Pillow-9.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e0918e03aa0c72ea56edbb00d4d664294815aa11291a11504a377ea018330d3"}, + {file = "Pillow-9.3.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0915e734b33a474d76c28e07292f196cdf2a590a0d25bcc06e64e545f2d146c"}, + {file = "Pillow-9.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af0372acb5d3598f36ec0914deed2a63f6bcdb7b606da04dc19a88d31bf0c05b"}, + {file = "Pillow-9.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:ad58d27a5b0262c0c19b47d54c5802db9b34d38bbf886665b626aff83c74bacd"}, + {file = "Pillow-9.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:97aabc5c50312afa5e0a2b07c17d4ac5e865b250986f8afe2b02d772567a380c"}, + {file = "Pillow-9.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9aaa107275d8527e9d6e7670b64aabaaa36e5b6bd71a1015ddd21da0d4e06448"}, + {file = "Pillow-9.3.0-cp39-cp39-win32.whl", hash = "sha256:bac18ab8d2d1e6b4ce25e3424f709aceef668347db8637c2296bcf41acb7cf48"}, + {file = "Pillow-9.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:b472b5ea442148d1c3e2209f20f1e0bb0eb556538690fa70b5e1f79fa0ba8dc2"}, + {file = "Pillow-9.3.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:ab388aaa3f6ce52ac1cb8e122c4bd46657c15905904b3120a6248b5b8b0bc228"}, + {file = "Pillow-9.3.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbb8e7f2abee51cef77673be97760abff1674ed32847ce04b4af90f610144c7b"}, + {file = "Pillow-9.3.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca31dd6014cb8b0b2db1e46081b0ca7d936f856da3b39744aef499db5d84d02"}, + {file = "Pillow-9.3.0-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c7025dce65566eb6e89f56c9509d4f628fddcedb131d9465cacd3d8bac337e7e"}, + {file = "Pillow-9.3.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ebf2029c1f464c59b8bdbe5143c79fa2045a581ac53679733d3a91d400ff9efb"}, + {file = "Pillow-9.3.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b59430236b8e58840a0dfb4099a0e8717ffb779c952426a69ae435ca1f57210c"}, + {file = "Pillow-9.3.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12ce4932caf2ddf3e41d17fc9c02d67126935a44b86df6a206cf0d7161548627"}, + {file = "Pillow-9.3.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae5331c23ce118c53b172fa64a4c037eb83c9165aba3a7ba9ddd3ec9fa64a699"}, + {file = "Pillow-9.3.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:0b07fffc13f474264c336298d1b4ce01d9c5a011415b79d4ee5527bb69ae6f65"}, + {file = "Pillow-9.3.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:073adb2ae23431d3b9bcbcff3fe698b62ed47211d0716b067385538a1b0f28b8"}, + {file = "Pillow-9.3.0.tar.gz", hash = "sha256:c935a22a557a560108d780f9a0fc426dd7459940dc54faa49d83249c8d3e760f"}, +] platformdirs = [ {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, {file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"}, @@ -1807,7 +2367,7 @@ py = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] -pygments = [ +Pygments = [ {file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"}, {file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"}, ] @@ -1820,8 +2380,8 @@ pyparsing = [ {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, ] pytest = [ - {file = "pytest-7.1.3-py3-none-any.whl", hash = "sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7"}, - {file = "pytest-7.1.3.tar.gz", hash = "sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39"}, + {file = "pytest-7.2.0-py3-none-any.whl", hash = "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71"}, + {file = "pytest-7.2.0.tar.gz", hash = "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59"}, ] pytest-cov = [ {file = "pytest-cov-4.0.0.tar.gz", hash = "sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470"}, @@ -1831,6 +2391,10 @@ pytest-mock = [ {file = "pytest-mock-3.10.0.tar.gz", hash = "sha256:fbbdb085ef7c252a326fd8cdcac0aa3b1333d8811f131bdcc701002e1be7ed4f"}, {file = "pytest_mock-3.10.0-py3-none-any.whl", hash = "sha256:f4c973eeae0282963eb293eb173ce91b091a79c1334455acfac9ddee8a1c784b"}, ] +python-dateutil = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] pytz = [ {file = "pytz-2022.5-py2.py3-none-any.whl", hash = "sha256:335ab46900b1465e714b4fda4963d87363264eb662aab5e65da039c25f1f5b22"}, {file = "pytz-2022.5.tar.gz", hash = "sha256:c4d88f472f54d615e9cd582a5004d1e5f624854a6a27a6211591c251f22a6914"}, @@ -1839,15 +2403,99 @@ requests = [ {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, ] +scipy = [ + {file = "scipy-1.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1884b66a54887e21addf9c16fb588720a8309a57b2e258ae1c7986d4444d3bc0"}, + {file = "scipy-1.9.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:83b89e9586c62e787f5012e8475fbb12185bafb996a03257e9675cd73d3736dd"}, + {file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a72d885fa44247f92743fc20732ae55564ff2a519e8302fb7e18717c5355a8b"}, + {file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d01e1dd7b15bd2449c8bfc6b7cc67d630700ed655654f0dfcf121600bad205c9"}, + {file = "scipy-1.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:68239b6aa6f9c593da8be1509a05cb7f9efe98b80f43a5861cd24c7557e98523"}, + {file = "scipy-1.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b41bc822679ad1c9a5f023bc93f6d0543129ca0f37c1ce294dd9d386f0a21096"}, + {file = "scipy-1.9.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:90453d2b93ea82a9f434e4e1cba043e779ff67b92f7a0e85d05d286a3625df3c"}, + {file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83c06e62a390a9167da60bedd4575a14c1f58ca9dfde59830fc42e5197283dab"}, + {file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abaf921531b5aeaafced90157db505e10345e45038c39e5d9b6c7922d68085cb"}, + {file = "scipy-1.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:06d2e1b4c491dc7d8eacea139a1b0b295f74e1a1a0f704c375028f8320d16e31"}, + {file = "scipy-1.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5a04cd7d0d3eff6ea4719371cbc44df31411862b9646db617c99718ff68d4840"}, + {file = "scipy-1.9.3-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:545c83ffb518094d8c9d83cce216c0c32f8c04aaf28b92cc8283eda0685162d5"}, + {file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d54222d7a3ba6022fdf5773931b5d7c56efe41ede7f7128c7b1637700409108"}, + {file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cff3a5295234037e39500d35316a4c5794739433528310e117b8a9a0c76d20fc"}, + {file = "scipy-1.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:2318bef588acc7a574f5bfdff9c172d0b1bf2c8143d9582e05f878e580a3781e"}, + {file = "scipy-1.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d644a64e174c16cb4b2e41dfea6af722053e83d066da7343f333a54dae9bc31c"}, + {file = "scipy-1.9.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:da8245491d73ed0a994ed9c2e380fd058ce2fa8a18da204681f2fe1f57f98f95"}, + {file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4db5b30849606a95dcf519763dd3ab6fe9bd91df49eba517359e450a7d80ce2e"}, + {file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c68db6b290cbd4049012990d7fe71a2abd9ffbe82c0056ebe0f01df8be5436b0"}, + {file = "scipy-1.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:5b88e6d91ad9d59478fafe92a7c757d00c59e3bdc3331be8ada76a4f8d683f58"}, + {file = "scipy-1.9.3.tar.gz", hash = "sha256:fbc5c05c85c1a02be77b1ff591087c83bc44579c6d2bd9fb798bb64ea5e1a027"}, +] +setuptools = [ + {file = "setuptools-65.5.0-py3-none-any.whl", hash = "sha256:f62ea9da9ed6289bfe868cd6845968a2c854d1427f8548d52cae02a42b4f0356"}, + {file = "setuptools-65.5.0.tar.gz", hash = "sha256:512e5536220e38146176efb833d4a62aa726b7bbff82cfbc8ba9eaa3996e0b17"}, +] +setuptools-scm = [ + {file = "setuptools_scm-7.0.5-py3-none-any.whl", hash = "sha256:7930f720905e03ccd1e1d821db521bff7ec2ac9cf0ceb6552dd73d24a45d3b02"}, + {file = "setuptools_scm-7.0.5.tar.gz", hash = "sha256:031e13af771d6f892b941adb6ea04545bbf91ebc5ce68c78aaf3fff6e1fb4844"}, +] +sgp4 = [ + {file = "sgp4-2.21-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f90ad26f34b06082538f61b64c8b89d69db28d750bf996ae67fd6b72c5e37f11"}, + {file = "sgp4-2.21-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0bbf00533e6afe0dc9569d71f7352a10e561ca39fa279f06f8d6029e96de2ed4"}, + {file = "sgp4-2.21-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dd3ad79125d71346cdb558b5e07b14b323013c31122f05fc6fcc87fe6c163b19"}, + {file = "sgp4-2.21-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9095cad9b143aa42ec8cfcb2d2cc96ea04e5d38fd4862096dd7b771445f71492"}, + {file = "sgp4-2.21-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2f742454d979a06d2d83ecb1eec69726ddc427e2d9f12ecefc94a90c2e1d8fc"}, + {file = "sgp4-2.21-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99738b05c2e5f0cd5b699f516cd3b3094d115b1e0cd5a80bda12612d9a7831dc"}, + {file = "sgp4-2.21-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0313db05662c74dad2e6148fca430b1672a01ea2e4d1b1b92439e4139d8577bc"}, + {file = "sgp4-2.21-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:339778069fb9aab5fbc5501270dafd9d3feb41fbfd8cab38f8e15d42ec716287"}, + {file = "sgp4-2.21-cp310-cp310-win32.whl", hash = "sha256:2d683e24b9f12c3e6431fd35b0cbbd37148f5deddfcfb737b85bf9720d7a42f9"}, + {file = "sgp4-2.21-cp310-cp310-win_amd64.whl", hash = "sha256:a32608a78ebe33ec18f03236f5d316387ba0c8bd8e9ef5ef12b9abce05d589af"}, + {file = "sgp4-2.21-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6ce02516e5d202faa9b7bea6436a9dc0d72158c4d94a69d5bb927715b691f822"}, + {file = "sgp4-2.21-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260a86c5b05ee5f8176cafe5e11bc35c1f66a245aef46da1322091e48cd4f21b"}, + {file = "sgp4-2.21-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70ccb6d43d5c5c9cec594f8907ca89f1c4db761f930c15229c3790ee5d535365"}, + {file = "sgp4-2.21-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1997347d39b49c9fbef0bb0c4fe6d41da658ec03b1f2186585dfd12b732d1de"}, + {file = "sgp4-2.21-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:bd552b2c8126aa2d24c648d2f3dc3d1f95263bc68a43befa220e9aa2820810f0"}, + {file = "sgp4-2.21-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:eff0e165547ef72ca47172b24f862ea8ba0969cbdcaf9e90f19d201188d0e1bd"}, + {file = "sgp4-2.21-cp36-cp36m-win32.whl", hash = "sha256:927bfeda7bc692d7569e4a54f1747527e2d1243a1a64b659a10a438e151622cc"}, + {file = "sgp4-2.21-cp36-cp36m-win_amd64.whl", hash = "sha256:d0be8c2cf790304c622bf5584fed85c355804c87b95103ce88dcb2ad7dacc465"}, + {file = "sgp4-2.21-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e1f6128d6df008905cabed04100e346ce56134054d4bcad73a1bf99d81e0e22e"}, + {file = "sgp4-2.21-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e14de495d5e2b466a84534e987b9e73c57cf7b2096446a0a4c587e59abe3a5b3"}, + {file = "sgp4-2.21-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b8efbe6b748b4628dedf082fdd08a216469bc58acc114e2f25a2debe6437194"}, + {file = "sgp4-2.21-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6002807220535ed39d144b192e342842553c60d7558a7fd3ec5092bbadd66e5"}, + {file = "sgp4-2.21-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b703d08ed4cee676189f44cd2e60e987c9334513b72b782250ae06ab4dcc5b87"}, + {file = "sgp4-2.21-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8d1bb424ee8fd8c9309d6aa0de76eb66897f9ea9d3b91d9dad2a45395ee2da41"}, + {file = "sgp4-2.21-cp37-cp37m-win32.whl", hash = "sha256:42d2616fc586cfa5677045f2f07a62bb21e9cafa7cb8089ac8b2367c6a561695"}, + {file = "sgp4-2.21-cp37-cp37m-win_amd64.whl", hash = "sha256:efe49faa3e57540ff6e74dabe2ab4ebbe709c00e5464df077f9ccdd2e8b303af"}, + {file = "sgp4-2.21-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:dde34366ce1b1c895962706ca61b09a02b9f9950afd3cbbb2bf7bc2dd5babcf8"}, + {file = "sgp4-2.21-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c4957c1302dd646656dc6dbca6b55871b7be2044773c591ade3e0ecfa7a56f1e"}, + {file = "sgp4-2.21-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1742dfb1395532af0f9aa9316bd53e416d2cd5f20545414fa7f08c8e14edc4e2"}, + {file = "sgp4-2.21-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0dbb484bcea946ef38cc0fe181a4e1ece832be6dde9fa5bf002e6fe8e3a168ef"}, + {file = "sgp4-2.21-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaccd598db4127449c1da92ee9a2da41305e186c47f0bbfd8b791ec4899ca5a1"}, + {file = "sgp4-2.21-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d09e256b83cf4624739b934f758baa8ee3aa77613b77dac447f3f10b69b14222"}, + {file = "sgp4-2.21-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:36a6aa7143671380ca962c371d09b67ad1570b14612661a90064669ed4347cef"}, + {file = "sgp4-2.21-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:959c05c30c79623df3077515e3cef0938ae97d062439425bf54369aa8a4472a8"}, + {file = "sgp4-2.21-cp38-cp38-win32.whl", hash = "sha256:91763c45ea6f63c525f49c513d941b5ea16cb0832b84bbf265c5a82e7ad5d552"}, + {file = "sgp4-2.21-cp38-cp38-win_amd64.whl", hash = "sha256:495a839bf7f3c8cb5a4de9685695d194b57c20ed13c0adbd7a0900a8ef8d4c19"}, + {file = "sgp4-2.21-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fca1848ca6a2ea2b23e781fb89483b84b1b50949f246cf8af61edc052ac837b9"}, + {file = "sgp4-2.21-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fea155d361540a764eca917f9fc55904862531e36f979d50daeb3f5ae176c43f"}, + {file = "sgp4-2.21-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2a128b93b62c4362db114dbc71c0fd5ab068917bd118f94fb4b8a2ae9d55d31d"}, + {file = "sgp4-2.21-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61b85bfdc4fd6636edf13c43af1b3e7811cf4f2759fdaeba5a9c6e9711d98908"}, + {file = "sgp4-2.21-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ed696d2c8da8216a60aac0ad9e892cb38472a54bc50eac491b01fe7701e1447"}, + {file = "sgp4-2.21-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a30084df6f8c5cfc5398fa5a6d9b259c944b2993f7f5ca08de4a40915cda7e7b"}, + {file = "sgp4-2.21-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7971de1c4b6f00c5f32923b274452b78d2bcb894396d4ac3baa215847c63cb9a"}, + {file = "sgp4-2.21-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3e02194a5f0170dab4ae628f2ba9fdf7e2439c0b39241835bf8a2987b59144f9"}, + {file = "sgp4-2.21-cp39-cp39-win32.whl", hash = "sha256:950257149dbac38e22e31a9b1af0dc8306b63a5fa404e5057f5368def8086120"}, + {file = "sgp4-2.21-cp39-cp39-win_amd64.whl", hash = "sha256:b7e70a0f6f702a6d021a8c90995224f5248957ad8685cadff48a085351a445c3"}, + {file = "sgp4-2.21.tar.gz", hash = "sha256:6179b875044877e941633c20af7722fd231a88d8a89af01bf30bd64f33cdecef"}, +] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +skyfield = [ + {file = "skyfield-1.45-py3-none-any.whl", hash = "sha256:fbfba0c9d5f764630b227d5a70e3f8f934ce9f7c04d6c47f021e3c33e810cd7a"}, + {file = "skyfield-1.45.tar.gz", hash = "sha256:5f0e0530bda6c9bf23a188c574181b4ee63cf2ce1ec1e0c8825f45ae577d8b36"}, +] snowballstemmer = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] -sphinx = [ +Sphinx = [ {file = "Sphinx-5.3.0.tar.gz", hash = "sha256:51026de0a9ff9fc13c05d74913ad66047e104f56a129ff73e174eb5c3ee794b5"}, {file = "sphinx-5.3.0-py3-none-any.whl", hash = "sha256:060ca5c9f7ba57a08a1219e547b269fadf125ae25b06b9fa7f66768efb652d6d"}, ] @@ -1892,12 +2540,12 @@ tomli = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] tomlkit = [ - {file = "tomlkit-0.11.5-py3-none-any.whl", hash = "sha256:f2ef9da9cef846ee027947dc99a45d6b68a63b0ebc21944649505bf2e8bc5fe7"}, - {file = "tomlkit-0.11.5.tar.gz", hash = "sha256:571854ebbb5eac89abcb4a2e47d7ea27b89bf29e09c35395da6f03dd4ae23d1c"}, + {file = "tomlkit-0.11.6-py3-none-any.whl", hash = "sha256:07de26b0d8cfc18f871aec595fda24d95b08fef89d147caa861939f37230bf4b"}, + {file = "tomlkit-0.11.6.tar.gz", hash = "sha256:71b952e5721688937fb02cf9d354dbcf0785066149d2855e44531ebdd2b65d73"}, ] tox = [ - {file = "tox-3.26.0-py2.py3-none-any.whl", hash = "sha256:bf037662d7c740d15c9924ba23bb3e587df20598697bb985ac2b49bdc2d847f6"}, - {file = "tox-3.26.0.tar.gz", hash = "sha256:44f3c347c68c2c68799d7d44f1808f9d396fc8a1a500cbc624253375c7ae107e"}, + {file = "tox-3.27.0-py2.py3-none-any.whl", hash = "sha256:89e4bc6df3854e9fc5582462e328dd3660d7d865ba625ae5881bbc63836a6324"}, + {file = "tox-3.27.0.tar.gz", hash = "sha256:d2c945f02a03d4501374a3d5430877380deb69b218b1df9b7f1d2f2a10befaf9"}, ] types-aiofiles = [ {file = "types-aiofiles-22.1.0.tar.gz", hash = "sha256:8ae2e1d2f99b62754cffe6a8761fd6eeb8a0675569dc73818248e5bc30cb9074"}, @@ -1956,8 +2604,8 @@ types-click-spinner = [ {file = "types_click_spinner-0.1.13-py3-none-any.whl", hash = "sha256:fe4c552026759f04504e0189e84d68a9d213990dbaa00357c507d3be27845a0e"}, ] types-colorama = [ - {file = "types-colorama-0.4.15.1.tar.gz", hash = "sha256:bc43687a0bf3f42115a56400bd53c618592cc611e66ff57d5cc95024cb44fb1a"}, - {file = "types_colorama-0.4.15.1-py3-none-any.whl", hash = "sha256:f35f0fc7b4e16d25cbd801b1f6e9d2123674d2561227624d0d7c5f97fac9a901"}, + {file = "types-colorama-0.4.15.2.tar.gz", hash = "sha256:157cbe66e16396596258464d38d78cae88d812eb3d7ab2a873e0daf4f47c6c89"}, + {file = "types_colorama-0.4.15.2-py3-none-any.whl", hash = "sha256:53c4a19f9aa8a5b30d5a1a330a720b393c289051d213f1926f237cbbb4ec0357"}, ] types-contextvars = [ {file = "types-contextvars-2.4.7.tar.gz", hash = "sha256:55f186a0935ea1c40e7e6d28a256ae7023ad640edd2b81b289947ff696b05da2"}, @@ -1979,7 +2627,7 @@ types-dateparser = [ {file = "types-dateparser-1.1.4.1.tar.gz", hash = "sha256:0f76578bbae15c8b8701b5efd94db98a97ce0a27aedfe6f14a531170de6db97d"}, {file = "types_dateparser-1.1.4.1-py3-none-any.whl", hash = "sha256:dd7b2343bb06225c0e358533609b66a8edfb95e5426d8f658664e7d0f27dea68"}, ] -types-datetimerange = [ +types-DateTimeRange = [ {file = "types-DateTimeRange-1.2.8.tar.gz", hash = "sha256:9d8753769a39cd30010ea4b5645517885c574666a1bad7cbebef20a580848914"}, {file = "types_DateTimeRange-1.2.8-py3-none-any.whl", hash = "sha256:d1e22f7cf6c1d5805a9e0c48eceaa95c4e5b9a2ed31ea56ab4bf5eb06029e19c"}, ] @@ -1987,7 +2635,7 @@ types-decorator = [ {file = "types-decorator-5.1.8.1.tar.gz", hash = "sha256:f9290cbe23d2674bb18a2d95f593c27547463ed459e0e604800c42099c3c6a44"}, {file = "types_decorator-5.1.8.1-py3-none-any.whl", hash = "sha256:da7218420e3efc8435c59654160300db43f685ef68709c933eaed124326b2755"}, ] -types-deprecated = [ +types-Deprecated = [ {file = "types-Deprecated-1.2.9.tar.gz", hash = "sha256:e04ce58929509865359e91dcc38720123262b4cd68fa2a8a90312d50390bb6fa"}, {file = "types_Deprecated-1.2.9-py3-none-any.whl", hash = "sha256:53d05621e1d75de537f5a57d93508c8df17e37c07ee60b9fb09d39e1b7586c1e"}, ] @@ -2019,7 +2667,7 @@ types-first = [ {file = "types-first-2.0.5.tar.gz", hash = "sha256:af9e144d9b2039d939237a0486670b22a9907df79d67bdbb3e4cb9f9ead3e5f4"}, {file = "types_first-2.0.5-py3-none-any.whl", hash = "sha256:4ef3d7370b9d8459ff78a55faa71f7d1d1694f447d195097006fb236aa973e85"}, ] -types-flask = [ +types-Flask = [ {file = "types-Flask-1.1.6.tar.gz", hash = "sha256:aac777b3abfff9436e6b01f6d08171cf23ea6e5be71cbf773aaabb1c5763e9cf"}, {file = "types_Flask-1.1.6-py3-none-any.whl", hash = "sha256:6ab8a9a5e258b76539d652f6341408867298550b19b81f0e41e916825fc39087"}, ] @@ -2047,11 +2695,11 @@ types-itsdangerous = [ {file = "types-itsdangerous-1.1.6.tar.gz", hash = "sha256:21c6966c10e353a5d35d36c82aaa2c5598d3bc32ddc8e0591276da5ad2e3c638"}, {file = "types_itsdangerous-1.1.6-py3-none-any.whl", hash = "sha256:aef2535c2fa0527dcce244ece0792b20ec02ee46533800735275f82a45a0244d"}, ] -types-jack-client = [ +types-JACK-Client = [ {file = "types-JACK-Client-0.5.10.tar.gz", hash = "sha256:f414261af3543d00ef539d11c7d69dfb61762df22c835b10a4af680cef6dda10"}, {file = "types_JACK_Client-0.5.10-py3-none-any.whl", hash = "sha256:b560addd30488356b44c0607bbfafa2ef3d71be7ad88367200d15faf545eade7"}, ] -types-jinja2 = [ +types-Jinja2 = [ {file = "types-Jinja2-2.11.9.tar.gz", hash = "sha256:dbdc74a40aba7aed520b7e4d89e8f0fe4286518494208b35123bcf084d4b8c81"}, {file = "types_Jinja2-2.11.9-py3-none-any.whl", hash = "sha256:60a1e21e8296979db32f9374d8a239af4cb541ff66447bb915d8ad398f9c63b2"}, ] @@ -2059,11 +2707,11 @@ types-kazoo = [ {file = "types-kazoo-0.1.3.tar.gz", hash = "sha256:97a3b95e2437fcc093506e822b009c1ee9e4db6906631b5320117f0d2be4aa4a"}, {file = "types_kazoo-0.1.3-py3-none-any.whl", hash = "sha256:885cb481b2af327f6ecae725c9e2770ece454c675b94ea5e367dbc76243e7418"}, ] -types-markdown = [ +types-Markdown = [ {file = "types-Markdown-3.4.2.1.tar.gz", hash = "sha256:03c0904cf5886a7d8193e2f50bcf842afc89e0ab80f060f389f6c2635c65628f"}, {file = "types_Markdown-3.4.2.1-py3-none-any.whl", hash = "sha256:b2333f6f4b8f69af83de359e10a097e4a3f14bbd6d2484e1829d9b0ec56fa0cb"}, ] -types-markupsafe = [ +types-MarkupSafe = [ {file = "types-MarkupSafe-1.1.10.tar.gz", hash = "sha256:85b3a872683d02aea3a5ac2a8ef590193c344092032f58457287fbf8e06711b1"}, {file = "types_MarkupSafe-1.1.10-py3-none-any.whl", hash = "sha256:ca2bee0f4faafc45250602567ef38d533e877d2ddca13003b319c551ff5b3cc5"}, ] @@ -2098,7 +2746,7 @@ types-pathlib2 = [ {file = "types-pathlib2-2.3.0.tar.gz", hash = "sha256:996981d3c39a3dd592bac06b4d87257c623f1acc3eef672f823d85c528b7a6ed"}, {file = "types_pathlib2-2.3.0-py3-none-any.whl", hash = "sha256:c69db9ca95e4577ddbca19abbab5d387fa55f40d5475b45854bfa1c2d0604c37"}, ] -types-pillow = [ +types-Pillow = [ {file = "types-Pillow-9.2.2.2.tar.gz", hash = "sha256:b88bd03d6b1d467d2dd1d54808b04631ca88941fe16f9eeb92bc114e5a145ec0"}, {file = "types_Pillow-9.2.2.2-py3-none-any.whl", hash = "sha256:49a633ad811446efeb2abbfea4596cff470b1a48adba6c944fae57b3a667e5cb"}, ] @@ -2111,8 +2759,8 @@ types-polib = [ {file = "types_polib-1.1.12-py3-none-any.whl", hash = "sha256:69b7f2ace26da54acbaeed0c476abef12770144ae2c94022d95d5912800037cb"}, ] types-protobuf = [ - {file = "types-protobuf-3.20.4.1.tar.gz", hash = "sha256:67df7cc7ec85d114db2664a8ae8905543e75fb5edbed437dabc9e9fb8f8fcf9e"}, - {file = "types_protobuf-3.20.4.1-py3-none-any.whl", hash = "sha256:c227975ffd0f6a1eb1754e9a3aa9ca3b12265e63b462e9761e824c41fd25331c"}, + {file = "types-protobuf-3.20.4.2.tar.gz", hash = "sha256:fd65ab8502f9a08e089f2cad26d52fab04cd57322cf896c570ab3391ca760bae"}, + {file = "types_protobuf-3.20.4.2-py3-none-any.whl", hash = "sha256:329bec368fd11a8cb95192b33aa61e59e0b30f659ec14be75301c651026c4cc1"}, ] types-pyaudio = [ {file = "types-pyaudio-0.2.16.tar.gz", hash = "sha256:4fcdc882fe4d316174086e3b94be0792030dd22c611e0f5011013742d9644d9f"}, @@ -2126,7 +2774,7 @@ types-pyfarmhash = [ {file = "types-pyfarmhash-0.3.1.tar.gz", hash = "sha256:82ee5383befb880359dd74ce3e8aa7b4af6ebadfd1ee6fc2c6244f3eb56508ae"}, {file = "types_pyfarmhash-0.3.1-py3-none-any.whl", hash = "sha256:3844c9c396e279e2e25a87312ef36bcf46b154951e1d59ef068442a5b43365b2"}, ] -types-pyjwt = [ +types-PyJWT = [ {file = "types-PyJWT-1.7.1.tar.gz", hash = "sha256:99c1a0d94d370951f9c6e57b1c369be280b2cbfab72c0f9c0998707490f015c9"}, {file = "types_PyJWT-1.7.1-py2.py3-none-any.whl", hash = "sha256:810112a84b6c060bb5bc1959a1d229830465eccffa91d8a68eeaac28fb7713ac"}, ] @@ -2134,11 +2782,11 @@ types-pymssql = [ {file = "types-pymssql-2.1.0.tar.gz", hash = "sha256:72e04114ce360a0606c3e78caab036636928ad52c4dd839e057932342774763e"}, {file = "types_pymssql-2.1.0-py3-none-any.whl", hash = "sha256:3a531f46f559bbedf242bde7c8dbee18200c32e830522fcc4c67ebf96215a169"}, ] -types-pymysql = [ +types-PyMySQL = [ {file = "types-PyMySQL-1.0.19.1.tar.gz", hash = "sha256:c24ce221cd76a24445b4614fff84b13644d7fb4966fc7a07a742e8546da29507"}, {file = "types_PyMySQL-1.0.19.1-py3-none-any.whl", hash = "sha256:6748b3d830b9fc0299bd85ebf0f4a29de8c51f452a11fee83690ee4b26deede8"}, ] -types-pyrfc3339 = [ +types-pyRFC3339 = [ {file = "types-pyRFC3339-1.1.1.tar.gz", hash = "sha256:8ed261737ae6a6e3e2af13d6018019b21538d8c275f46127c58aaecb56b1a58f"}, {file = "types_pyRFC3339-1.1.1-py3-none-any.whl", hash = "sha256:000892a34456cb8aad06ed3b35839d00d71addb686437669dc0e2f7d40366b32"}, ] @@ -2166,9 +2814,9 @@ types-pyvmomi = [ {file = "types-pyvmomi-7.0.8.2.tar.gz", hash = "sha256:b7c961ce1527a0582534c47d9519bab870fa3ea2b2ea1c57c420246f96d152ef"}, {file = "types_pyvmomi-7.0.8.2-py3-none-any.whl", hash = "sha256:97148c99e70a2cf17558d901268b6b5a1b4fd5024b9867cf75b1a4464d060f1e"}, ] -types-pyyaml = [ - {file = "types-PyYAML-6.0.12.tar.gz", hash = "sha256:f6f350418125872f3f0409d96a62a5a5ceb45231af5cc07ee0034ec48a3c82fa"}, - {file = "types_PyYAML-6.0.12-py3-none-any.whl", hash = "sha256:29228db9f82df4f1b7febee06bbfb601677882e98a3da98132e31c6874163e15"}, +types-PyYAML = [ + {file = "types-PyYAML-6.0.12.1.tar.gz", hash = "sha256:70ccaafcf3fb404d57bffc1529fdd86a13e8b4f2cf9fc3ee81a6408ce0ad59d2"}, + {file = "types_PyYAML-6.0.12.1-py3-none-any.whl", hash = "sha256:aaf5e51444c13bd34104695a89ad9c48412599a4f615d65a60e649109714f608"}, ] types-redis = [ {file = "types-redis-4.3.21.3.tar.gz", hash = "sha256:2e1f184056188c8754ded0b5173dc01824d2bfe41975fe318068a68beedfb62c"}, @@ -2182,7 +2830,7 @@ types-retry = [ {file = "types-retry-0.9.9.tar.gz", hash = "sha256:b1087b274680b542c796549e8488898d0b22cd89988ef1016ef56d4367ff4f41"}, {file = "types_retry-0.9.9-py3-none-any.whl", hash = "sha256:c5208407527661c37ee826a81abe8e7560e138c8deeccce61bf3f5441f2085f0"}, ] -types-routes = [ +types-Routes = [ {file = "types-Routes-2.5.0.tar.gz", hash = "sha256:df7ab143c02821a749a4ba7c26fc697c2482c8fcb8f3032c509eecfcaf6d5951"}, {file = "types_Routes-2.5.0-py3-none-any.whl", hash = "sha256:9267c82633b8866bde9a1fa594c6040ca8fda29e7cc9a0e633a24b7900aa957e"}, ] @@ -2219,8 +2867,8 @@ types-tornado = [ {file = "types_tornado-5.1.1-py3-none-any.whl", hash = "sha256:69b603360db4e64453dcb932efa9a152d7fd99bf7553b67902c9a3ecf4ba57e7"}, ] types-typed-ast = [ - {file = "types-typed-ast-1.5.8.tar.gz", hash = "sha256:156fbaca903e8571fe70bb0b562ffba92a7cbdb7bac9a713351ca27d88183ba7"}, - {file = "types_typed_ast-1.5.8-py3-none-any.whl", hash = "sha256:386f54c807d8adc6215fcbdf2f301ddab5aedab0f9d875e85720c1af730dd64e"}, + {file = "types-typed-ast-1.5.8.1.tar.gz", hash = "sha256:f64c15ec04c0911819ac4c0fd0052795132001fbf5ea23d1d7e4fead7de49bfc"}, + {file = "types_typed_ast-1.5.8.1-py3-none-any.whl", hash = "sha256:5178b31c345734a6fe43764a71273b22637aa8c41c62ed5aadfd09960cbb5fd3"}, ] types-tzlocal = [ {file = "types-tzlocal-4.2.2.1.tar.gz", hash = "sha256:85fcbc84b233398be489c931a568affe471fa3983f0d7d723a9d9335f2e6bc2a"}, @@ -2238,7 +2886,7 @@ types-waitress = [ {file = "types-waitress-2.1.4.1.tar.gz", hash = "sha256:cc749963a95b0d2e64beebf4d24cdc90fca31c6a64f5396ed7a7284f402b59bf"}, {file = "types_waitress-2.1.4.1-py3-none-any.whl", hash = "sha256:e475d0abac5c888cd2409cd3308a8fba1f5a5809734274f18b0f70fe328cc143"}, ] -types-werkzeug = [ +types-Werkzeug = [ {file = "types-Werkzeug-1.0.9.tar.gz", hash = "sha256:5cc269604c400133d452a40cee6397655f878fc460e03fde291b9e3a5eaa518c"}, {file = "types_Werkzeug-1.0.9-py3-none-any.whl", hash = "sha256:194bd5715a13c598f05c63e8a739328657590943bce941e8a3619a6b5d4a54ec"}, ] @@ -2255,8 +2903,8 @@ urllib3 = [ {file = "urllib3-1.26.12.tar.gz", hash = "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e"}, ] virtualenv = [ - {file = "virtualenv-20.16.5-py3-none-any.whl", hash = "sha256:d07dfc5df5e4e0dbc92862350ad87a36ed505b978f6c39609dc489eadd5b0d27"}, - {file = "virtualenv-20.16.5.tar.gz", hash = "sha256:227ea1b9994fdc5ea31977ba3383ef296d7472ea85be9d6732e42a91c04e80da"}, + {file = "virtualenv-20.16.6-py3-none-any.whl", hash = "sha256:186ca84254abcbde98180fd17092f9628c5fe742273c02724972a1d8a2035108"}, + {file = "virtualenv-20.16.6.tar.gz", hash = "sha256:530b850b523c6449406dfba859d6345e48ef19b8439606c5d74d7d3c9e14d76e"}, ] wrapt = [ {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"}, @@ -2324,6 +2972,10 @@ wrapt = [ {file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"}, {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, ] +xarray = [ + {file = "xarray-2022.10.0-py3-none-any.whl", hash = "sha256:e4e574820ff8eb7dbc119c5089d30860b73160bd587cc045ae37a128b8eb4fc2"}, + {file = "xarray-2022.10.0.tar.gz", hash = "sha256:b39ff3475f73eaacdf831b0ab7eb6930e7b5933e46dcf71b9327f4c4bb941793"}, +] zipp = [ {file = "zipp-3.10.0-py3-none-any.whl", hash = "sha256:4fcb6f278987a6605757302a6e40e896257570d11c51628968ccb2a47e80c6c1"}, {file = "zipp-3.10.0.tar.gz", hash = "sha256:7a7262fd930bd3e36c50b9a64897aec3fafff3dfdeec9623ae22b40e93f99bb8"}, diff --git a/pyproject.toml b/pyproject.toml index 70913c9..89be98e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,10 +2,26 @@ name = "adcs_simulation" version = "0.1.0" description = "Attitude Determination and Control System simulation for WroSat satellite project." -authors = ["Arek Drabik "] +authors = [ + "Arek Drabik ", + "Jan Bronicki ", +] [tool.poetry.dependencies] python = "^3.8" +matplotlib = "^3.6.1" +pandas = "^1.5.1" +scipy = "^1.9.3" +numpy = "^1.23.4" +tomli = "^2.0.1" +pytz = "^2022.5" +sgp4 = "^2.21" +skyfield = "^1.45" +python-dateutil = "^2.8.2" +jplephem = "^2.18" +igrf = "^13.0.2" +fonttools = "^4.38.0" +Pillow = "^9.3.0" [tool.poetry.group.format.dependencies] black = "^22.10.0" diff --git a/src/adcs_simulation/adcs.py b/src/adcs_simulation/adcs.py new file mode 100644 index 0000000..2302904 --- /dev/null +++ b/src/adcs_simulation/adcs.py @@ -0,0 +1,980 @@ +""" +Main module for ADCS simulation. + +""" + +import math +from dataclasses import dataclass + +import igrf +import numpy as np +import pandas as pd + +from adcs_simulation.configuration.config import Config +from adcs_simulation.propagator import Propagator, eci_2_sb_transformation +from adcs_simulation.visualization import visualize + + +@dataclass +class Result: + """ + Class responsible for parsing results + """ + + pqr_table: pd.DataFrame + state_vector: pd.DataFrame + sun_table: pd.Series + mag_field: pd.DataFrame + angle: pd.DataFrame + + +def simulate(cfg: Config, propagator: Propagator) -> Result: + """ + Main simulation code. + + The ADCS simulation is responsible to obtain orientation and + position data of the satellite. Initial parameters such as + time step control, initial Euler Angles and rotational + velocity are loaded from setup.json file. For position + the SGP4 propagator is utilized. To solve differential + equations describing the satellites behavior the + Runge-Kutta method (4th order) was used. It is an iterative + algorithm to obtain approximate solutions. + + + Parameters + ---------- + cfg: Config - initial parameters from setup.json + propagator: Propagator - data computed using the SGP4 + propagator such as: position and velocity in GCRS + coordinate system, LLA (latitude, longitude, attitude), + Sun vector in ECI frame and SB frame. + + Returns + ------- + Results - appends the time step data to the following: + pqr_table - data frame containing summary for different types of + rotation velocity (magnetic, sun etc.) + state_vector - data frame with summary information about + the satellite, contains position, linear and rotation + velocity, LLA + sun_table - data frame with sun vector in ECI and SB frames + mag_field - data frame with different types of magnetic field values + angle - data frame with angle between two subsequent Sun vectors + """ + + tzero, tend, tstep = cfg.iterations_info + state_vector, quaternions, mag_field, pqr_table, sun_table = initial_step( + tzero, cfg, propagator + ) + angle = {"phi": 0, "theta": 0, "psi": 0} + angle = pd.DataFrame(data=angle, index=[0]) + # TODO: angle was a variable for debug, check what it is and if its necessary + + for delta_t in np.arange(tzero + 1, tend, tstep): + print("Timestep {delta_t}") + + part_of_day = delta_t / (60 * 60 * 24) + pos_gcrs, v_gcrs, lla, sun_sb, sun_eci = propagator.propagate( + part_of_day, quaternions[-1] + ) + + pqr_sun, sun_table, angle = pqr_from_sun(sun_sb, sun_eci, sun_table) + + pqr_rk4, quaternion_rk4, mag_field, pqr_filt = rk4( + delta_t, + lla, + state_vector.values[delta_t - 1], + quaternions[delta_t - 1], + mag_field, + pqr_table, + cfg, + ) + + pqr_table = update_pqr(pqr_rk4, pqr_filt, pqr_sun, pqr_table) + quaternions, state_vector = update_data( + state_vector, pos_gcrs, v_gcrs, lla, pqr_rk4, quaternions, quaternion_rk4 + ) + + return Result( + pqr_table=pqr_table, + state_vector=state_vector, + sun_table=sun_table, + mag_field=mag_field, + angle=angle, + ) + + +def initial_step(tzero: int, config: Config, propagator: Propagator): + """ + Initialize the simulation for time zero. + + The first step starts from initial orientation parameters + given in setup json. Propagation is executed for time t zero. + + In this part of the code where tables to store data during the + simulation time steps are initialized. They are in form + of pandas data frames. + + Parameters + ---------- + tzero : int - simulation start time + config : object - initial parameters from setup.json + propagator: Propagator - data computed using the SGP4 + propagator such as: position and velocity in GCRS + coordinate system, LLA (latitude, longitude, attitude), + Sun vector in ECI frame and SB frame. + + Returns + ------- + pqr_table - data frame containing rotation velocities of the satellite. + Two based on magnetic field, measured (with bias), filtered + (utilizing a simple filter algorithm) and one computed from + the Sun vector change. + state_vector - data frame with summary information about + the satellite, contains position, linear and rotation + velocity, LLA + sun_table - data frame with sun vector in ECI and SB frames + mag_field - data frame with magnetic field values, similarly to the + pqr values one measured and one filtered. Both ale in ECI frame. + quaternions : list - a list where previous quaternions are stored + + """ + + p0, q0, r0 = config.rotation + phi0, theta0, psi0 = config.euler_angles + + quat0 = euler_to_quaternion(phi0, theta0, psi0) + quaternions = [quat0] + + pos_gcrs, v_gcrs, lla, sun_sb, sun_eci = propagator.propagate( + tzero / (60 * 60 * 24), quat0 + ) + col = { + "x km": pos_gcrs[0], + "y km": pos_gcrs[1], + "z km": pos_gcrs[2], + "dx/dt km/s": v_gcrs[0], + "dy/dt km/s": v_gcrs[1], + "dz/dt km/s": v_gcrs[2], + "p rad/s": p0, + "q rad/s": q0, + "r rad/s": r0, + "longtitude": lla[0].degrees, + "latitude": lla[1].degrees, + "altitude": lla[2], + } + state_vector = pd.DataFrame(data=col, index=[0]) + + print("Evaluating initial time step for timestep {tzero}, state vector: \n") + print(state_vector) + print("\n") + + empty_b = { + "B_x": 0.0, + "B_y": 0.0, + "B_z": 0.0, + "B_x_filt": 0.0, + "B_y_filt": 0.0, + "B_z_filt": 0.0, + } + mag_field = pd.DataFrame(data=empty_b, index=[0]) + + init_pqr = { + "p": p0, + "q": q0, + "r": r0, + "p_filt": p0, + "q_filt": q0, + "r_filt": r0, + "p_sun": p0, + "q_sun": q0, + "r_sun": r0, + } + pqr_table = pd.DataFrame(data=init_pqr, index=[0]) + + init_sun = { + "X": sun_sb[0], + "Y": sun_sb[1], + "Z": sun_sb[2], + "X_ECI": sun_eci[0], + "Y_ECI": sun_eci[1], + "Z_ECI": sun_eci[2], + } + sun_table = pd.DataFrame(data=init_sun, index=[0]) + + return state_vector, quaternions, mag_field, pqr_table, sun_table + + +def pqr_from_sun(sun_sb: list, sun_eci: list, sun_table: pd.DataFrame): + """ + Function to calculate the satellite rotational velocity from the Sun + vector measurement. + + At first the function updates the sun_table by the Sun vector results + from the current step. Then the te two last rows are taken to obtain + the angle between them. Rotation velocity can be calculated as: + Δangle/Δtime, as the time step is 1s this can be expressed directly + as the angle between two iterations of the Sun vector + + + Parameters + ---------- + sun_sb : list - the x, y and z components of the Sun vector in SB frame. + The vector is directly expressed as the position of the Sun in SB frame. + It was transformed from ECI frame. + sun_eci : list - the x, y and z components of the Sun vector in ECI frame. + Also expressed as the position of the Sun in ECI frame. + sun_table : pd.DataFrame - a frame containing the Sun vectors in ECI and + SB frames from the previous steps + + Returns + ------- + pqr : list - 3-element list with rotation velocity about all axes obtained + from Sun vector + sun_table : pd.DataFrame - a frame containing the Sun vectors in ECI and + SB frames from the previous steps, now updated by the current step + angle - the total angle between the two subsequent Sun vectors + """ + + sun_step = { + "X": sun_sb[0], + "Y": sun_sb[1], + "Z": sun_sb[2], + "X_ECI": sun_eci[0], + "Y_ECI": sun_eci[1], + "Z_ECI": sun_eci[2], + } + df2 = pd.DataFrame(data=sun_step, index=[0]) + sun_table = pd.concat([sun_table, df2]) + + s_vector0 = sun_table.values[-2] + s_vector0 = s_vector0[:3] / np.linalg.norm(s_vector0[:3]) + s_vector1 = sun_table.values[-1] + s_vector1 = s_vector1[:3] / np.linalg.norm(s_vector1[:3]) + + if sum(s_vector0) == 0 or sum(s_vector1) == 0: + pqr = [0, 0, 0] + + else: + dot_product = np.dot(s_vector0, s_vector1) + cross_product = np.cross(s_vector0, s_vector1) + cross_product = ( + -1 * cross_product / np.linalg.norm(cross_product) + ) # nie wiem czemu razy -1 ale dziala + angle = np.arccos(np.clip(dot_product, -1.0, 1.0)) + + deltaphi = angle * cross_product[0] + deltatheta = angle * cross_product[1] + deltapsi = angle * cross_product[2] + + # assumption: if dt = 1s -> p ~ detlaphi, q ~ deltatheta, r ~ deltapsi + pqr = [deltaphi, deltatheta, deltapsi] + + return pqr, sun_table, angle + + +def update_pqr( + pqr_rk4: np.array, pqr_filt: np.array, pqr_sun: list, pqr_table: pd.DataFrame +) -> pd.DataFrame: + """ + Update the sun_table data frame by calculated in the current step values + of different rotational velocities. + + Parameters + ---------- + pqr_rk4 : np.array - rotational velocity calculated using the + Runge-Kutte algorithm based on magnetic field measurement + pqr_filt : np.array - rotational velocity computed from the previous + RK4 version first by adding bias the applying a filter. + pqr : list - 3-element list with rotation velocity about all axes obtained + from Sun vector + pqr_table : DataFrame - data frame containing rotation velocities of the satellite. + Two based on magnetic field, measured (with bias), filtered + (utilizing a simple filter algorithm) and one computed from + the Sun vector change. + + Returns + ------- + pqr_table: DataFrame - data frame containing rotation velocities of the satellite. + Two based on magnetic field, measured (with bias), filtered + (utilizing a simple filter algorithm) and one computed from + the Sun vector change. Now updated by the current step. + """ + + step_pqr = { + "p": pqr_rk4[0], + "q": pqr_rk4[1], + "r": pqr_rk4[2], + "p_filt": pqr_filt[0], + "q_filt": pqr_filt[1], + "r_filt": pqr_filt[2], + "p_sun": pqr_sun[0], + "q_sun": pqr_sun[1], + "r_sun": pqr_sun[2], + } + df2 = pd.DataFrame(data=step_pqr, index=[0]) + pqr_table = pd.concat([pqr_table, df2]) + + return pqr_table + + +def euler_to_quaternion(phi: float, theta: float, psi: float) -> list[float]: + """ + Mathematical function to transform the Euler angles rotation + representation into a quaternion representation. + + Parameters + ---------- + phi : float - rotation around the X Axis in radians + theta : float - rotation around the Y Axis in radians + psi : float - rotation around the Z Axis in radians + + Returns + ------- + qauternion : list - quaternion representation of the given Euler angles. The initial + orientation is given as the axis of ECI (Earth Centered Inertial) frame. + A quaternion contains four elements (here in form of a list). Three + of the elements are vectors and only one is a scalar: + q = iq1 + jq2 + kq3 + q4, + where i, j and are describing the vector which is the rotation axis + The q1 to q3 can be written as sin(alfa/2) and q4 cos(alfa/2), + where alfa is the angle of rotation around the given axis. + """ + + # TODO: check the input angles (radians or degrees) + + qat0 = math.cos(phi / 2) * math.cos(theta / 2) * math.cos(psi / 2) + math.sin( + phi / 2 + ) * math.sin(theta / 2) * math.sin(psi / 2) + qat1 = math.sin(phi / 2) * math.cos(theta / 2) * math.cos(psi / 2) - math.cos( + phi / 2 + ) * math.sin(theta / 2) * math.sin(psi / 2) + qat2 = math.cos(phi / 2) * math.sin(theta / 2) * math.cos(psi / 2) + math.sin( + phi / 2 + ) * math.cos(theta / 2) * math.sin(psi / 2) + qat3 = math.cos(phi / 2) * math.cos(theta / 2) * math.sin(psi / 2) - math.sin( + phi / 2 + ) * math.sin(theta / 2) * math.cos(psi / 2) + + qauternion = [qat0, qat1, qat2, qat3] + + return qauternion + + +def ned_2_eci_transformation(ned: list, xyz: np.array) -> np.array: + """ + Function to transform vector given in NED (North-East-Down) frame to + ECI (Earth Centered Inertial) frame. + + Parameters + ---------- + ned : list - 3D vector in NED frame. In the NED frame X Axis points to + true North, Z Axis points towards the Earth center, Y Axis completes + the right-handed system (points East) + xyz : np.array - X, Y and Z coordinates of the object given as a + vector in ECI frame + + Returns + ------- + eci : np.array - input vector transformed into ECI frame. Dot product of + the computed rotation matrix and input vector + """ + + # TODO rewrite using scipy rotation library + rho = np.linalg.norm(xyz) + x_coord = xyz[0] + y_coord = xyz[1] + z_coord = xyz[2] + + phi_e = 0 + theta_e = np.arccos(z_coord / rho) + np.pi + psi_e = np.arctan2(y_coord, x_coord) + + cost = np.cos(theta_e) + sint = np.sin(theta_e) + sinp = np.sin(phi_e) + cosp = np.cos(phi_e) + sins = np.sin(psi_e) + coss = np.cos(psi_e) + + rot_mat = [ + [ + cost * coss, + sinp * sint * coss - cosp * sins, + cosp * sint * coss + sinp * sins, + ], + [ + cost * sins, + sinp * sint * sins + cosp * coss, + cosp * sint * sins - sinp * coss, + ], + [-sint, sinp * cost, cosp * cost], + ] + eci = np.dot(rot_mat, ned) + + return eci + + +def quaternion_diff(pqr: np.array, quaternion: list[float]): + """ + Mathematical function to obtain the the differential of a quaternion + dq/dt for a given rotation with the given rotation velocity. + + Parameters + ---------- + pqr : np.array - array whit the current rotation velocity of the object + in radians in SB (Satellite Body) frame + quaternion : list[float] - quaternion describing the rotation from the + ECI axis to the current orientation + + Returns + ------- + quaternion_dot : np.array - differential quaternion + """ + + p = pqr[0] + q = pqr[1] + r = pqr[2] + + prq_matrix = np.array( + [[0, -p, -q, -r], [p, 0, r, -q], [q, -r, 0, p], [r, q, -p, 0]] + ) + quat = np.array(quaternion) + quaternion_dot = np.dot(0.5 * prq_matrix, quat) + + return quaternion_dot + + +def pollute_signal(b_sb: np.array, pqr: np.array) -> np.array: + """ + Short function to pollute the magnetic field and rotation velocity + calculation to imitate real measurements. + + Parameters + ---------- + b_sb : np.array - calculated magnetic field vector given in the SB + (Satellite Body) frame + pqr : np.array - calculated rotation velocity vector given in the SB + (Satellite Body) frame + + Returns + ------- + polluted_b_SB : np.array - the input magnetic field updated by bias and noise + polluted_pqr : np.array - the input rotation velocity updated by bias + and noise + """ + + # TODO: random values from -1 to 1? why 0 to 1 * 2 used? + # Bias and Noise + magscale_bias = 4e-7 # T + mag_field_bias = magscale_bias * (2 * np.random.rand()) # (0 to 1) + + magscale_noise = 1e-5 # T + mag_field_noise = magscale_noise * (2 * np.random.rand()) # (0 to 1) + + angscale_bias = 0.01 # rad/s + ang_field_bias = angscale_bias * (2 * np.random.rand()) # (0 to 1) + + angscale_noise = 0.001 # rad/s + ang_field_noise = angscale_noise * (2 * np.random.rand()) # (0 to 1) + + polluted_pqr = np.zeros(3) + polluted_b_sb = np.zeros(3) + + for x in range(3): + polluted_b_sb[x] = b_sb[x] + mag_field_bias + mag_field_noise + polluted_pqr[x] = pqr[x] + ang_field_bias + ang_field_noise + + return np.array(polluted_b_sb), np.array(polluted_pqr) + + +def filter_signal( + b_poluted: np.array, + pqr_poluted: np.array, + mag_field: pd.DataFrame, + pqr_table: pd.DataFrame, +) -> np.array: + """ + Simple filter for the polluted data. + + Takes the previous data for magnetic field and rotation velocity and the + current values which were polluted to simulate a real measurement. + As we assume rather small values and small changes in time the new filtered + value is taken as a sum of parts of the previous value and measured: + new value = current * s + previous * (1-s), + where we rather thrust the previous values default using s = 0.3 to + avoid step changes from measurement errors. + Estimated bias should be also subtracted from the measured values, but + at this time we assume them as 0. + + Parameters + ---------- + b_poluted : np.array - magnetic field in SB (Satellite Body) frame with + added pollution to simulate real measurements + pqr_poluted : np.array - rotation velocity in SB (Satellite Body) frame + with added pollution to simulate real measurements + mag_field : pd.DataFrame - table with saved magnetic field data to get + the values from the previous step + pqr_table : pd.DataFrame - table with saved rotation velocity data to get + the values from the previous step + + Returns + ------- + b_field_nav : np.array - array with the filtered (navigation) + magnetic field + pqr_nav : np.array - array with the filtered (navigation) + rotation velocity + """ + + if all(mag_field[-1]) == 0: + b_field_nav = b_poluted + pqr_nav = pqr_poluted + else: + b_prev = np.array(mag_field[-1][3:]) + pqr_prev = np.array(pqr_table[-1][3:6]) + + s = 0.3 + + bias_estimate = [0, 0, 0] + b_field_nav = b_prev * (1 - s) + s * (b_poluted - bias_estimate) + pqr_bias_estimate = [0, 0, 0] + pqr_nav = pqr_prev * (1 - s) + s * (pqr_poluted - pqr_bias_estimate) + + return b_field_nav, pqr_nav + + +def magnetorquer(b_sb_filt: np.array, pqr_filt: np.array, config: Config): + """ + Magnetotorquer model. Calculates current and magnetic induction of the solenoid. + + An ADCS module consists of three solenoids for every axis of rotation to + perform a three-axis control. + + Parameters + ---------- + b_sb_filt : np.array - filtered magnetic field in SB (Satellite Body) frame. + pqr_filt : np.array - filtered rotation velocity of the satellite. + config : Config - initial parameters from setup.json. In this situation + required for solenoid parameters + + Returns + ------- + current : np.array - calculated current required on the solenoids for every + axis of rotation + mu_b : float - magnetic induction generated on every of the three solenoids. + """ + + # TODO check the physics + n_coils, area = config.torquer_params + k = 67200 + current = k * np.cross(pqr_filt, b_sb_filt) / (n_coils * area) + + # Add in saturation + if np.abs(np.max(current)) > 0.04: + current = current / np.linalg.norm(current) * 0.04 + mu_b = current * n_coils * area + + return current, mu_b + + +def rot_dynamics( + mu_b: np.array, b_sb: np.array, pqr: np.array, config: Config +) -> np.array: + """ + Perform rotation dynamic calculations. + + The desired magnetic induction on every solenoid is calculated using the + magnetorquer model and assuming that the goal is to slow the satellite + rotation down to zero (no other control variants are implemented yet). + The calculated in this way magnetic induction in the Earth Magnetic field + allows to obtain the electromagnetic force and rotation velocity + derivative + + Parameters + ---------- + mu_b : np.array - magnetic induction generated on every of the three solenoids. + b_sb : np.array - filtered magnetic field in SB (Satellite Body) frame. + pqr : np.array - filtered rotation velocity of the satellite. + config : Config- initial parameters from setup.json. In this situation + required for satellite parameters + + Returns + ------- + pqr_dot : np.array - rotation velocity derivative for this time step + """ + + inertia, stellite_mass = config.sat_params + + torquer_model = np.dot(mu_b, b_sb) + ang_momentum = np.dot(inertia, pqr) + inv_inertia = np.linalg.inv(np.array(inertia)) + pqr = np.array(pqr) + + pqr_dot = np.dot( + np.array(inv_inertia), (torquer_model - np.cross(pqr, ang_momentum)) + ) + + return pqr_dot + + +# def trans_dynamics(xyz: list, config: Config): +# inertia, satellite_mass = config.sat_params +# gravity_const, earth_mass, earth_radius = config.planet_data + +# rho = np.linalg.norm(xyz) +# rhat = xyz / rho +# force_grav = -(gravity_const * earth_mass * satellite_mass / rho ** 2) * rhat + +# accel = force_grav / satellite_mass + +# return accel + + +def k_function( + time: int, + lla: list, + quaternion: list, + pqr: np.array, + xyz: np.array, + mag_field: pd.DataFrame, + pqr_table: pd.DataFrame, + config: Config, + rewrite: bool, +): + """ + Runge-Kutta Method partial function. Computes values of the chosen + parameters. For explanation of the method see rk4 function. + + The main goal is to calculate derivatives for quaternion and rotation + velocity. As to obtain rotation velocity the magnetic field is needed + every 10 time steps, when dt = 1 an update is calculated using the + IGRF model. In other situations the magnetic field value is taken from + the last updated step. + + Parameters + ---------- + t : int - time from simulation start in seconds + lla : list - position in LLA frame: latitude, longitude, altitude (in km) + quaternion : list - a 4-element array describing 3D rotations. The given + quaternion gives the relation between the ECI frame (Earth Centered + Inertial, in this case GCRS frame) and satellite orientation + (Satellite Body Frame - SB). It can be used to obtain the rotation + matrix or directly rotate vector between these reference frames. + pqr : np.array - array whit the current rotation velocity of the object + in radians in SB (Satellite Body) frame + xyz : np.array - X, Y and Z coordinates of the object given as a + vector in ECI frame + mag_field : pd.DataFrame - data frame with different types of magnetic + field values + pqr_table : pd.DataFrame - data frame containing rotation velocities + of the satellite. Two based on magnetic field, measured (with bias), + filtered (utilizing a simple filter algorithm) and one computed from + the Sun vector change. + config : Config - initial parameters from setup.json + rewrite : bool - secondary check if the calculated values should be saved + + Returns + ------- + mag_field : pd.DataFrame - data frame with different types of magnetic + field values. Eventually updated + pqr_table : pd.DataFrame - data frame containing rotation velocities + of the satellite. Two based on magnetic field, measured (with bias), + filtered (utilizing a simple filter algorithm) and one computed from + the Sun vector change. Eventually updated. + dstat_dt : np.array - array with derivatives for quaternion and rotation + velocity calculated in this step + """ + + quaternion_dot = quaternion_diff(pqr, quaternion) + if time % 10 == 0: + mag = igrf.igrf( + "2020-01-01", glat=lla[0].degrees, glon=lla[1].degrees, alt_km=lla[2] + ) + + b_ned = [mag["north"][0], mag["east"][0], mag["down"][0]] + b_eci = ned_2_eci_transformation(b_ned, xyz) + b_sb = eci_2_sb_transformation(b_eci, quaternion) + b_sb = b_sb * 1e-9 + else: + b_sb = mag_field.values[-1][:3] + + if time % 10 == 0 and rewrite is True: + b_sb_measured, pqr_measured = pollute_signal(b_sb, pqr) + b_sb_filt, pqr_filt = filter_signal( + b_sb_measured, pqr_measured, mag_field.values, pqr_table.values + ) + b_step = { + "B_x": b_sb[0], + "B_y": b_sb[1], + "B_z": b_sb[2], + "B_x_filt": b_sb_filt[0], + "B_y_filt": b_sb_filt[1], + "B_z_filt": b_sb_filt[2], + } + df2 = pd.DataFrame(data=b_step, index=[0]) + mag_field = pd.concat([mag_field, df2]) + + pqr_step = { + "p": pqr[0], + "q": pqr[1], + "r": pqr[2], + "p_filt": pqr_filt[0], + "q_filt": pqr_filt[1], + "r_filt": pqr_filt[2], + } + df2 = pd.DataFrame(data=pqr_step, index=[0]) + pqr_table = pd.concat([pqr_table, df2]) + + elif time % 10 != 0 and rewrite is True: + b_sb_filt = mag_field.values[-1][3:6] + pqr_filt = pqr_table.values[-1][3:6] + b_step = { + "B_x": b_sb[0], + "B_y": b_sb[1], + "B_z": b_sb[2], + "B_x_filt": b_sb_filt[0], + "B_y_filt": b_sb_filt[1], + "B_z_filt": b_sb_filt[2], + } + df2 = pd.DataFrame(data=b_step, index=[0]) + mag_field = pd.concat([mag_field, df2]) + pqr_step = { + "p": pqr[0], + "q": pqr[1], + "r": pqr[2], + "p_filt": pqr_filt[0], + "q_filt": pqr_filt[1], + "r_filt": pqr_filt[2], + } + df2 = pd.DataFrame(data=pqr_step, index=[0]) + pqr_table = pd.concat([pqr_table, df2]) + else: + b_sb_filt = mag_field.values[-1][3:6] + pqr_filt = pqr_table.values[-1][3:6] + b_step = { + "B_x": b_sb[0], + "B_y": b_sb[1], + "B_z": b_sb[2], + "B_x_filt": b_sb_filt[0], + "B_y_filt": b_sb_filt[1], + "B_z_filt": b_sb_filt[2], + } + pqr_step = { + "p": pqr[0], + "q": pqr[1], + "r": pqr[2], + "p_filt": pqr_filt[0], + "q_filt": pqr_filt[1], + "r_filt": pqr_filt[2], + } + + current, mu_b = magnetorquer(b_sb_filt, pqr_filt, config) + pqr_dot = rot_dynamics(mu_b, b_sb, pqr, config) + + dstat_dt = np.array( + [ + quaternion_dot[0], + quaternion_dot[1], + quaternion_dot[2], + quaternion_dot[3], + pqr_dot[0], + pqr_dot[1], + pqr_dot[2], + ] + ) + + return dstat_dt, mag_field, pqr_filt + + +def rk4( + time: int, + lla: list, + state_vector: pd.DataFrame, + quaternion: list, + mag_field: pd.DataFrame, + pqr_table: pd.DataFrame, + config: Config, +): + """ + Runge-Kutte method is iterative an algorithm to obtain approximate + solutions for differential equations. + + The common RK4 method is based on four partial functions. If we have an + equation where dy/dt = f(t,y), assume a time step of Δt = 1 and have + the solution on time n then we can approximate the function + for time n + 1: + yn+1 = yn + 1/6(k1 + 2*k2 + 2*k3 + k4)*Δt + + where: + tn = t + Δt + k1 = f(tn, yn) - this is the initial value + k2 = f(tn + Δt/2, yn + Δt*k1/2) + k3 = f(tn + Δt/2, yn + Δt*k2/2) + k4 = f(tn + Δt, yn + Δt*k3) + + Parameters + ---------- + t : int - time from simulation start in seconds + lla : list - position in LLA frame: latitude, longitude, altitude (in km) + quaternion : list - a 4-element array describing 3D rotations. The given + quaternion gives the relation between the ECI frame (Earth Centered + Inertial, in this case GCRS frame) and satellite orientation + (Satellite Body Frame - SB). It can be used to obtain the rotation + state_vector : pd.DataFrame - data frame with summary information about + the satellite, contains position, linear and rotation + quaternion : list - a 4-element array describing 3D rotations. The given + quaternion gives the relation between the ECI frame (Earth Centered + Inertial, in this case GCRS frame) and satellite orientation + (Satellite Body Frame - SB). It can be used to obtain the rotation + matrix or directly rotate vector between these reference frames. + mag_field : pd.DataFrame - data frame with different types of magnetic + field values + pqr_table : pd.DataFrame - data frame containing rotation velocities + of the satellite. Two based on magnetic field, measured (with bias), + filtered (utilizing a simple filter algorithm) and one computed from + the Sun vector change. + config : Config - initial parameters from setup.json + + Returns + ------- + mag_field : pd.DataFrame - data frame with different types of magnetic + field values. Eventually updated + pqr_table : pd.DataFrame - data frame containing rotation velocities + of the satellite. Two based on magnetic field, measured (with bias), + filtered (utilizing a simple filter algorithm) and one computed from + the Sun vector change. Eventually updated. + pqr1 : np.array - rotation velocity estimated using the RK4 method + quaternion1 : list - quaternion estimated using RK4 method + """ + + time0, tend, tstep = config.iterations_info + + pqr = np.array([state_vector[6], state_vector[7], state_vector[8]]) + xyz = np.array([state_vector[0], state_vector[1], state_vector[2]]) + v_xyz = np.array([state_vector[3], state_vector[4], state_vector[5]]) + k1, mag_field, pqr_filt = np.array( + k_function( + time, lla, quaternion, pqr, xyz, mag_field, pqr_table, config, rewrite=True + ), + dtype=object, + ) + k2, mag_field, temp = np.array( + k_function( + time + tstep / 2, + lla, + quaternion + k1[0:4] * tstep / 2, + pqr + k1[4:7] * tstep / 2, + xyz + v_xyz * tstep / 2, + mag_field, + pqr_table, + config, + rewrite=False, + ), + dtype=object, + ) + k3, mag_field, temp = np.array( + k_function( + time + tstep / 2, + lla, + quaternion + k2[0:4] * tstep / 2, + pqr + k2[4:7] * tstep / 2, + xyz + v_xyz * tstep / 2, + mag_field, + pqr_table, + config, + rewrite=False, + ), + dtype=object, + ) + k4, mag_field, temp = np.array( + k_function( + time + tstep, + lla, + quaternion + k3[0:4] * tstep, + pqr + k3[4:7] * tstep, + xyz + v_xyz * tstep, + mag_field, + pqr_table, + config, + rewrite=False, + ), + dtype=object, + ) + + k = np.array((1 / 6) * (k1 + 2 * k2 + 2 * k3 + k4)) + pqr1 = pqr + k[4:7] * tstep + quaternion1 = quaternion + k[0:4] * tstep + + return pqr1, quaternion1, mag_field, pqr_filt + + +def update_data( + state_vector: list, + pos_gcrs: np.ndarray, + v_gcrs: np.array, + lla: list, + pqr_rk4: np.array, + quaternions: list, + quaternion: list, +): + """ + Update the main tables that save revelant data for the time step. + + Parameters + ---------- + state_vector : pd.DataFrame - data frame with summary information about + the satellite, contains position, linear and rotation + pos_gcrs - object position in GCRS frame given in km. + v_gcrs - velocity vector in GCRS frame given in km/s. + lla - position given in LLA frame, attitude in km. + pqr_rk4 : np.array - rotation velocity estimated using the RK4 method + quaternions : list - a list where previous quaternions are stored + quaternion : list - a 4-element array describing 3D rotations. The given + quaternion gives the relation between the ECI frame (Earth Centered + Inertial, in this case GCRS frame) and satellite orientation + (Satellite Body Frame - SB). It can be used to obtain the rotation + matrix or directly rotate vector between these reference frames. + + Returns + ------- + quaternions : list - updated list where previous quaternions are stored + state_vector : pd.DataFrame - data frame with summary information about + the satellite, contains position, linear and rotation, updated + """ + + col = { + "x km": pos_gcrs[0], + "y km": pos_gcrs[1], + "z km": pos_gcrs[2], + "dx/dt km/s": v_gcrs[0], + "dy/dt km/s": v_gcrs[1], + "dz/dt km/s": v_gcrs[2], + "p rad/s": pqr_rk4[0], + "q rad/s": pqr_rk4[1], + "r rad/s": pqr_rk4[2], + "longtitude": lla[0].degrees, + "latitude": lla[1].degrees, + "altitude": lla[2], + } + temp_state_vector = pd.DataFrame(data=col, index=[0]) + state_vector = pd.concat([state_vector, temp_state_vector]) + + quaternions.append(quaternion) + return quaternions, state_vector + + +def main(): + """ + Main function for the simulation + """ + + cfg = Config("ADCS_setup.json") + propagator = Propagator("tle.txt") + result = simulate(cfg, propagator) + gravity_const, earth_mass, earth_radius = cfg.planet_data + visualize(result, earth_radius) + + +if __name__ == "__main__": + main() diff --git a/src/adcs_simulation/configuration/ADCS_setup.json b/src/adcs_simulation/configuration/ADCS_setup.json new file mode 100644 index 0000000..4cb34f6 --- /dev/null +++ b/src/adcs_simulation/configuration/ADCS_setup.json @@ -0,0 +1,45 @@ +{ + "PlanetConst" : [ + { + "R" : 6.371e6, + "M" : 5.972e24, + "G" : 6.67e-11, + "Unit_info" : "m, kg, m^3/(kg*s^2)" + } + ], + + "Satelite" : [ + { + "mass" : 2, + "I" : [[0.9, 0, 0], [0, 0.9, 0], [0, 0, 0.3]], + "Unit_info" : "kg, kg*m^2" + } + + ], + + "Initial" : [ + { + "EulerAngles" : [10, 20, 30], + "rotVelocity" : [0.01, 0, 0.01], + "Unit_info" : "deg, rad/s" + } + ], + + "iterations" : [ + { + "start" : 0, + "stop" : 1400, + "step" : 1, + "Unit_info" : "s" + } + ], + + "magnetorquer" : [ + { + "n" : 84, + "A" : 2, + "Unit_info" : "coils, cm^2" + } + ] + +} \ No newline at end of file diff --git a/src/adcs_simulation/configuration/__init__.py b/src/adcs_simulation/configuration/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/adcs_simulation/configuration/config.py b/src/adcs_simulation/configuration/config.py new file mode 100644 index 0000000..ccd2c29 --- /dev/null +++ b/src/adcs_simulation/configuration/config.py @@ -0,0 +1,144 @@ +"""Module that handles configuration of simulation.""" + +import json +import os +from pathlib import Path +from typing import Any + +ROOT_DIR = Path(__file__).parents[3] +CONFIG_DIR = os.path.dirname(os.path.abspath(__file__)) +EXAMPLE_DATA_DIR = os.path.join(ROOT_DIR, "example_data") + + +class Config: + """ + Get the configuration data from setup. + """ + + def __init__(self, setup_file: str) -> None: + setup_path = os.path.join(CONFIG_DIR, setup_file) + self._setup = self._read_setup(setup_path) + + def _read_setup(self, setup_file: str) -> Any: + """ + Read the setup file. + + Parameters + ---------- + setup_file : str - name of the file. Default setup.json + + Returns + ------- + Loaded json file. + + Raises + ------ + RuntimeError - raise error if the setup file was not found. + """ + if not Path(setup_file).exists(): + raise RuntimeError(f"Setup file not found at: {setup_file}") + with open(Path(setup_file), "r") as file: + return json.load(file) + + @property + def euler_angles(self) -> tuple: + """ + Get the initial Euler Angles. + + Returns + ------- + phi0 : int - initial Euler Angle around the X Axis in degrees + theta0 : int - initial Euler Angle around the Y Axis in degrees + psi0 : int - initial Euler Angle around the Z Axis in degrees + """ + euler_angles = self._setup["Initial"][0]["EulerAngles"] + phi0 = euler_angles[0] + theta0 = euler_angles[1] + psi0 = euler_angles[2] + + return phi0, theta0, psi0 + + @property + def rotation(self) -> tuple: + """ + Get the initial rotation velocity. + + Returns + ------- + p0 : float - initial rotation velocity around the X Axis in rad/s + q0 : float - initial rotation velocity around the Y Axis in rad/s + r0 : float - initial rotation velocity around the Z Axis in rad/s + """ + omega = self._setup["Initial"][0]["rotVelocity"] + p0 = omega[0] + q0 = omega[1] + r0 = omega[2] + + return p0, q0, r0 + + @property + def iterations_info(self) -> tuple: + """ + Get the time control settings. + + Returns + ------- + time0 : int - beginning time, default 0 + tend : int - end time in seconds + tstep : int - time step, default 1 second + """ + time0 = self._setup["iterations"][0]["start"] + tend = self._setup["iterations"][0]["stop"] + tstep = self._setup["iterations"][0]["step"] + + return time0, tend, tstep + + @property + def torquer_params(self) -> tuple: + """ + Get the parameters of the magnetorquer. + + Returns + ------- + n : int - number of coils on one solenoid + area : int/float - solenoid cross-section area + """ + + n = self._setup["magnetorquer"][0]["n"] + area = self._setup["magnetorquer"][0]["A"] + + return n, area + + @property + def sat_params(self) -> tuple: + """ + Satellite kinematic parameters + + Returns + ------- + inertia : list - inertia matrix of the mass + mass : int/float - satellite mass + """ + + inertia = self._setup["Satelite"][0]["I"] + mass = self._setup["Satelite"][0]["mass"] + + return inertia, mass + + @property + def planet_data(self) -> tuple: + """ + Earth constants + + Returns + ------- + gravity_const : float - gravitational constant + earth_mass : float - Earth mass in kg + earth_radius : float - Earth radius in m + """ + + gravity_const = self._setup["PlanetConst"][0]["G"] + earth_mass = self._setup["PlanetConst"][0]["M"] + earth_radius = self._setup["PlanetConst"][0]["R"] + + return gravity_const, earth_mass, earth_radius diff --git a/src/adcs_simulation/de421.bsp b/src/adcs_simulation/de421.bsp new file mode 100644 index 0000000..ed5b583 Binary files /dev/null and b/src/adcs_simulation/de421.bsp differ diff --git a/src/adcs_simulation/propagator.py b/src/adcs_simulation/propagator.py new file mode 100644 index 0000000..ba45b47 --- /dev/null +++ b/src/adcs_simulation/propagator.py @@ -0,0 +1,234 @@ +""" +Module for propagator calculations. + +""" + +import os + +import numpy as np +import sgp4.api as sgp +import skyfield.api as skyfield + +from adcs_simulation.configuration.config import EXAMPLE_DATA_DIR +from adcs_simulation.utils import read_tle + + +def eci_2_sb_transformation(v_eci: list, quaternion: list): + """ + Function to transform vector given in ECI (Earth Centered Inertial) frame + to SB (Satellite Body) frame. + + Parameters + ---------- + eci : list - input vector transformed into ECI frame. Dot product of + the computed rotation matrix and input vector + quat : list - a 4-element array describing 3D rotations. The given + quaternion gives the relation between the ECI frame (Earth Centered + Inertial, in this case GCRS frame) and satellite orientation + (Satellite Body Frame - SB). It can be used to obtain the rotation + + Returns + ------- + sb : np.array - input vector transformed into SB frame. Dot product of + the computed rotation matrix and input vector + """ + + # TODO: change to scipy rotation + quat0 = quaternion[0] + quat1 = quaternion[1] + quat2 = quaternion[2] + quat3 = quaternion[3] + + rot_mat = np.array( + [ + [ + (quat0**2 + quat1**2 - quat2**2 - quat3**2), + 2 * (quat1 * quat2 - quat0 * quat3), + 2 * (quat0 * quat2 + quat1 * quat3), + ], + [ + 2 * (quat1 * quat2 + quat0 * quat3), + (quat0**2 - quat1**2 + quat2**2 - quat3**2), + 2 * (quat2 * quat3 - quat0 * quat1), + ], + [ + 2 * (quat1 * quat3 - quat0 * quat2), + 2 * (quat0 * quat1 + quat2 * quat3), + (quat0**2 - quat1**2 - quat2**2 + quat3**2), + ], + ] + ) + rot_mat = np.transpose(rot_mat) + v_sb = np.dot(rot_mat, v_eci) + + return v_sb + + +def get_sunpos(time: skyfield): + """ + Calculates the position of the Sun relative to Earth in the + Earth Centered Inertial Frame. + + Parameters + ---------- + time : float - given as Julian Date in form of skyfield Timescale object + + Returns + ------- + sunpos : list - containing of 6 elements: + sunpos[0] - X coordinate of the Sun vector in ECI frame + sunpos[1] - Y coordinate of the Sun vector in ECI frame + sunpos[2] - Z coordinate of the Sun vector in ECI frame + sunpos[3] - right ascension - angular distance of a + particular point measured eastward along the celestial + equator from the Sun at the March equinox, in radians + sunpos[4] - declination in radians + sunpos[5] - distance to the Sun meters + + """ + time = time.tt + time = time - 2451595 + rad = np.pi / 180 + mean_longtitude = np.mod((280.460 + 0.9856474 * time) * rad, 2 * np.pi) + + if mean_longtitude < 0: + mean_longtitude = mean_longtitude + 2 * np.pi + + mean_anomaly = np.mod((357.528 + 0.9856003 * time) * rad, 2 * np.pi) + if mean_anomaly < 0: + mean_anomaly = mean_anomaly + 2 * np.pi + + mean_anomaly_2 = mean_anomaly + mean_anomaly + + if mean_anomaly_2 > 2 * np.pi: + mean_anomaly_2 = np.mod(mean_anomaly_2, 2 * np.pi) + + ecliptic_longtitude = ( + mean_longtitude + + (1.915 * np.sin(mean_anomaly) + 0.02 * np.sin(mean_anomaly_2)) * rad + ) + sin_ecli_lo = np.sin(ecliptic_longtitude) + cos_ecli_lo = np.cos(ecliptic_longtitude) + + # ecliptic_latitude = 0 + + obliquity = ( + 23.439 - 4.0e-7 * time + ) * rad # obliquity of the ecliptic (nachylenie osi) + sin_obl_ecli = np.sin(obliquity) + cos_obl_ecli = np.cos(obliquity) + + astronomical_unit = 149.60e09 + sunpos = [0, 0, 0, 0, 0, 0] + sunpos[3] = np.arctan2( + cos_obl_ecli * sin_ecli_lo, cos_ecli_lo + ) # right ascension - angular distance of a particular point measured eastward + # along the celestial equator from the Sun at the March equinox, in radians + if sunpos[3] < 0: + sunpos[3] = sunpos[3] + 2 * np.pi + + sunpos[4] = np.arcsin(sin_obl_ecli * sin_ecli_lo) # declination, in radians + sunpos[5] = ( + 1.00014 - 0.01671 * np.cos(mean_anomaly) - 1.4e-4 * np.cos(mean_anomaly_2) + ) * astronomical_unit # distance vector in meters + + # sun position in the the rectangular equatorial coordinate system in meteres + sunpos[0] = sunpos[5] * cos_ecli_lo + sunpos[1] = sunpos[5] * cos_obl_ecli * sin_ecli_lo + sunpos[2] = sunpos[5] * sin_obl_ecli * sin_ecli_lo + + return sunpos + + +class Propagator: + """ + Class which utilizes the SGP4 propagator. + """ + + def __init__(self, tle_file: str) -> None: + """ + Get satellite data for propagation from TEL. + + Parameters + ---------- + tle_file : str - TLE file name + """ + + self._tle = read_tle(os.path.join(EXAMPLE_DATA_DIR, tle_file)) + + def propagate(self, part_of_day, quaternion): + """ + Performs calculations to obtain satellite position using SGP4 propagator + + Using the previously loaded TLE text file initializes the satellite model + using skyfield library. The time given in form of Julian Date allows to + propagate the object position on orbit in the GCRS frame (Geocentric + Celestial Reference System - a type of Earth centered inertial coordinate + frame which is related to its center of mass) as well as its kinematic + parameters. + A transformation to LLA format (Latitude, Longitude, Attitude) is also + performed and the Sun vector (a vector pointing towards the Sun center) + computed. + + Parameters + ---------- + part_of_day - time from t0 given as 'part of day' to easy sum with JD + quaternion - a 4-element array describing 3D rotations. The given + quaternion gives the relation between the ECI frame (Earth Centered + Inertial, in this case GCRS frame) and satellite orientation + (Satellite Body Frame - SB). It can be used to obtain the rotation + matrix or directly rotate vector between these reference frames. + + Returns + ------- + pos_gcrs - object position in GCRS frame given in km. + v_gcrs - velocity vector in GCRS frame given in km/s. + lla - position given in LLA frame, attitude in km. + sun_eci - Sun vector given in the ECI frame. If the object is in + Earths shadow returned as [0, 0, 0]. + sun_sb - Sun vector given in the SB frame. The transformation was + obtained from sun_ECI using the given quaternion. If the object + is in Earths shadow returned as [0, 0, 0]. + + """ + + satellite = skyfield.EarthSatellite( + self._tle.first_line, self._tle.second_line + ) # initialize TLE + + time_scale = skyfield.load.timescale() # initialize time + + month, day, hour, minute, second = sgp.days2mdhms( + self._tle.year, float(self._tle.day) + float(self._tle.epoch) + part_of_day + ) + julian_date = time_scale.utc(self._tle.year, month, day, hour, minute, second) + # TODO replace using skyfiled library + + # GCRS is and ECI frame almost similar do J2000 + gcrs = satellite.at(julian_date) + pos_gcrs = gcrs.position.km + v_gcrs = gcrs.velocity.km_per_s + + lat, lon = skyfield.wgs84.latlon_of(gcrs) + + # get the altitude as difference between Earth surface position and satelite position + bluffton = skyfield.wgs84.latlon(lat.degrees, lon.degrees) + position_difference = satellite - bluffton + topocentric = position_difference.at(julian_date) + alt, azimuth, distance = topocentric.altaz() + + lla = [lat, lon, distance.km] + + eph = skyfield.load("de421.bsp") + sunlight = satellite.at(julian_date).is_sunlit(eph) + + if sunlight: + sunposition = get_sunpos(julian_date) + sun_eci = [sunposition[0], sunposition[1], sunposition[2]] + sun_sb = eci_2_sb_transformation(sun_eci, quaternion) + + else: + sun_sb = [0, 0, 0] + sun_eci = [0, 0, 0] + + return pos_gcrs, v_gcrs, lla, sun_eci, sun_sb diff --git a/src/adcs_simulation/utils.py b/src/adcs_simulation/utils.py new file mode 100644 index 0000000..5fd4033 --- /dev/null +++ b/src/adcs_simulation/utils.py @@ -0,0 +1,104 @@ +""" +Module with utility functions. + +""" + + +from dataclasses import dataclass + + +@dataclass +class TLE: + """ + Class dedicated to read given two-line-element (TLE) + """ + + first_line: str + second_line: str + + sat_number: str + classification: str + international_designator: str + year: str + day: str + epoch: str + first_mean_motion: str + second_mean_motion: str + second_mean_motion_exp: str + bstar_drag: str + bstar_drag_exp: str + ephemeris: str + norad_number: str + + inclination: str + right_ascension: str + eccentricity: str + arg_perigee: str + mean_anomaly: str + mean_motion: str + revolutions: str + + +def _convert_tle_year(tle: TLE) -> None: + """ + Check the year written in TLE file. + + Parameters + ---------- + tle : TLE - two-line-element for the satellite + + """ + + if 57 <= tle.year <= 99: + tle.year += 1900 + elif 0 <= tle.year <= 56: + tle.year += 2000 + else: + raise ValueError(f"Invalid year in TLE data: {tle.year=}") + + +def read_tle(tle_file: str) -> TLE: + """ + Read the TLE from txt file. + + Parameters + ---------- + tle_file : str - TLE file name + + Returns + ------- + TLE + """ + + with open(tle_file) as file: + tle = file.read() + tle_lines = tle.split(sep="\n") + tle = tle.split(sep=" ") + + tle[:] = [x for x in tle if x] + _tle = TLE( + first_line=tle_lines[0], + second_line=tle_lines[1], + sat_number=tle[1][:-1], + classification=tle[1][-1], + international_designator=tle[2], + year=int(tle[3][0:2]), + day=tle[3][2:5], + epoch="0{tle[3][5:]}", + first_mean_motion=tle[4], + second_mean_motion=tle[5][:-2], + second_mean_motion_exp=tle[5][-2:], + bstar_drag=tle[6][:-2], + bstar_drag_exp=tle[6][-2:], + ephemeris=tle[7], + norad_number=tle[8][:-2], + inclination=tle[10], + right_ascension=tle[11], + eccentricity=tle[12], + arg_perigee=tle[13], + mean_anomaly=tle[14], + mean_motion=tle[15][:-5], + revolutions=tle[15][-5:], + ) + _convert_tle_year(_tle) + return _tle diff --git a/src/adcs_simulation/visualization.py b/src/adcs_simulation/visualization.py new file mode 100644 index 0000000..2361cf9 --- /dev/null +++ b/src/adcs_simulation/visualization.py @@ -0,0 +1,137 @@ +""" +Module for visualising data. + +""" + +import os +from typing import Any + +import matplotlib.pyplot as plt +import numpy as np + + +def visualize(result: Any, radius: float): + """ + Function dedicated to plot the most important parameters + + Created plots: + - 3D plot of the orbit in ECEF (Earth Centered Earth Fixed) frame. + - Rotation velocity calculated from magnetic field. + - Rotation velocity calculated from Sun vector. + - Measured magnetic field. + + Parameters + ---------- + results + radius : float - Earth + """ + + sun_table = result.sun_table + angle = result.angle + state_vector = result.state_vector + mag_field = result.mag_field + pqr_table = result.pqr_table + + sun_table.to_csv("sun_table.csv", index=False) + angle.to_csv("angles.csv", index=False) + print(state_vector) + print(mag_field) + print(pqr_table) + + os.mkdir("../../plots") + + fig = plt.figure() + axis = fig.gca(projection="3d") + axis.set_aspect("auto") + # draw sphere + u, v = np.mgrid[0 : 2 * np.pi : 40j, 0 : np.pi : 20j] + x_coordinate = np.cos(u) * np.sin(v) * radius / 1000 + y_coordinate = np.sin(u) * np.sin(v) * radius / 1000 + z_coordinate = np.cos(v) * radius / 1000 + + axis.title("Orbit ECEF") + # ax.plot_surface(x, y, z, cmap=plt.cm.YlGnBu_r) + axis.plot_wireframe(x_coordinate, y_coordinate, z_coordinate, color="g") + axis.scatter( + state_vector["x km"], + state_vector["y km"], + state_vector["z km"], + color="r", + s=20, + ) + plt.savefig() + plt.show() + plt.close("../../plots/orbit_ECEF") + + plt.title("Position ECEF") + plt.grid() + plt.plot(range(len(state_vector["x km"])), state_vector["x km"]) + plt.plot(range(len(state_vector["x km"])), state_vector["y km"]) + plt.plot(range(len(state_vector["x km"])), state_vector["z km"]) + plt.xlabel("time [s]") + plt.ylabel("position [km]") + plt.legend(["x", "y", "z"], loc="best") + plt.savefig("../../plots/position_ECEF.png", dpi=720) + + plt.show() + plt.close() + + plt.title("Satellite body rotation (magnetic field)") + plt.grid() + plt.plot(range(len(state_vector["x km"])), pqr_table["p"], label="p") + plt.plot(range(len(state_vector["x km"])), pqr_table["q"], label="q") + plt.plot(range(len(state_vector["x km"])), pqr_table["r"], label="r") + plt.plot( + range(len(state_vector["x km"])), + np.sqrt( + state_vector["p rad/s"] ** 2 + + state_vector["q rad/s"] ** 2 + + state_vector["r rad/s"] ** 2 + ), + label="omega", + ) + plt.xlabel("time [s]") + plt.ylabel("rotation [rad/s]") + plt.legend(loc="best") + plt.savefig("../../plots/mag_rotation.png", dpi=720) + + plt.show() + plt.close() + + plt.title("Satliette body rotation (sun vector)") + plt.grid() + plt.plot(range(len(state_vector["x km"])), pqr_table["p_sun"], label="p") + plt.plot(range(len(state_vector["x km"])), pqr_table["q_sun"], label="q") + plt.plot(range(len(state_vector["x km"])), pqr_table["r_sun"], label="r") + plt.plot( + range(len(state_vector["x km"])), + np.sqrt( + pqr_table["p_sun"] ** 2 + pqr_table["q_sun"] ** 2 + pqr_table["r_sun"] ** 2 + ), + label="omega", + ) + plt.xlabel("time [s]") + plt.ylabel("rotation [rad/s]") + plt.legend(loc="best") + plt.savefig("../../plots/sun_rotation.png", dpi=720) + + plt.show() + plt.close() + + plt.title("Magnetic field SBRF") + plt.grid() + plt.plot(range(len(state_vector["x km"])), mag_field["B_x"], label="X") + plt.plot(range(len(state_vector["x km"])), mag_field["B_y"], label="Y") + plt.plot(range(len(state_vector["x km"])), mag_field["B_z"], label="Z") + plt.plot( + range(len(state_vector["x km"])), + np.sqrt(mag_field["B_z"] ** 2 + mag_field["B_y"] ** 2 + mag_field["B_x"] ** 2), + label="Summary", + ) + plt.xlabel("time [s]") + plt.ylabel("Magnetic field [T]") + plt.legend(loc="best") + plt.savefig("../../plots/mag_field.png", dpi=720) + + plt.show() + plt.close() diff --git a/tox.ini b/tox.ini index 1c3ccea..7e9e7b4 100644 --- a/tox.ini +++ b/tox.ini @@ -115,6 +115,7 @@ commands= skip_install = true whitelist_externals={[project-info]whitelist_externals} commands= + poetry install poetry install --only lint poetry install --only test {[commands]cmd_pylint} {posargs} @@ -125,6 +126,7 @@ commands= skip_install = true whitelist_externals={[project-info]whitelist_externals} commands= + poetry install poetry install --only type_check {[commands]cmd_mypy} {posargs}