diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..1aac30a --- /dev/null +++ b/.flake8 @@ -0,0 +1,2 @@ +[flake8] +extend-ignore = E741, E302, E128, E501 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 8ee8084..d21be97 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +.venv/ + *.project *.pydevproject *.settings diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..6324d40 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.14 diff --git a/README.md b/README.md new file mode 100644 index 0000000..96ca7e0 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# pycopan-more + +This repository contains additional model components and example models using the [copan:CORE modelling framework](http://www.pik-potsdam.de/copan), developed at the Potsdam Institute for Climate Impact Research. + +The base reference implementation can be found in [pik-copan/pycopancore](https://github.com/pik-copan/pycopancore). + +## Running the models + +To run the models, first, setup your environment. The recommended way is using [uv](https://docs.astral.sh/uv/) for that: + +```console +$ uv sync +$ uv pip install . +``` + +However, you can also set up using pure Python: + +```console +$ python -m venv .venv +$ source .venv/bin/activate +$ pip install . +``` + +You can then run the models with `uv`. For example, for the seven dwarfs model, run: `uv run studies/seven_dwarfs.py`. + +## Known issues + +Some of the models showcased here have since fallen out of date and are no longer maintained to the current version of [pik-copan/pycopancore](https://github.com/pik-copan/pycopancore). Models which we know do not work: + +- `models/exploit.py` +- `models/adaptive_voter_model.py` +- `models/carbon_voters_anderies_model.py` +- `models/example*.py` +- `models/coccon` + +Other models will be fixed, once https://github.com/pik-copan/pycopancore/issues/213 and https://github.com/pik-copan/pycopancore/issues/211 are addressed. + +For more information on current problems and to track the progress on fixing them, see https://github.com/pik-copan/pycopanmodels/issues/2. \ No newline at end of file diff --git a/pycopan_more/model_components/adaptive_voter_opinion_formation/implementation/culture.py b/pycopan_more/model_components/adaptive_voter_opinion_formation/implementation/culture.py index 4e420e6..30ba451 100644 --- a/pycopan_more/model_components/adaptive_voter_opinion_formation/implementation/culture.py +++ b/pycopan_more/model_components/adaptive_voter_opinion_formation/implementation/culture.py @@ -14,10 +14,10 @@ # License: BSD 2-clause license from .. import interface as I -#from .... import master_data_model as D -from .... import Step +#from pycopancore.data_model import master_data_model as D +from pycopancore.process_types import Step -from ....runners import Hooks +from pycopancore.runners import Hooks # from blist import sortedlist # more performant for large list modifications diff --git a/pycopan_more/model_components/adaptive_voter_opinion_formation/implementation/individual.py b/pycopan_more/model_components/adaptive_voter_opinion_formation/implementation/individual.py index 3e0b012..7e1a51e 100644 --- a/pycopan_more/model_components/adaptive_voter_opinion_formation/implementation/individual.py +++ b/pycopan_more/model_components/adaptive_voter_opinion_formation/implementation/individual.py @@ -14,9 +14,7 @@ # License: BSD 2-clause license from .. import interface as I -#from .... import master_data_model as D - -import random +#from pycopancore.data_model import master_data_model as D class Individual (I.Individual): diff --git a/pycopan_more/model_components/adaptive_voter_opinion_formation/interface.py b/pycopan_more/model_components/adaptive_voter_opinion_formation/interface.py index 8a15754..ade849f 100644 --- a/pycopan_more/model_components/adaptive_voter_opinion_formation/interface.py +++ b/pycopan_more/model_components/adaptive_voter_opinion_formation/interface.py @@ -14,13 +14,12 @@ # License: BSD 2-clause license # TODO: use variables from the master data model wherever possible: -from ... import master_data_model as D +from pycopancore.data_model import master_data_model as D # TODO: uncomment and adjust of you need further variables from another # model component: # import ..BBB.interface as BBB # TODO: uncomment and adjust only if you really need other variables: -from ... import Variable # used for opinion here, maybe that should be included in the master data model? But I wouldn't know how? something like discrete opinion -from ..base import interface as baseI +from pycopancore.data_model import Variable # used for opinion here, maybe that should be included in the master data model? But I wouldn't know how? something like discrete opinion class Model (object): diff --git a/pycopan_more/model_components/anderies_carbon_cycle/implementation/cell.py b/pycopan_more/model_components/anderies_carbon_cycle/implementation/cell.py index 4529986..163fb52 100644 --- a/pycopan_more/model_components/anderies_carbon_cycle/implementation/cell.py +++ b/pycopan_more/model_components/anderies_carbon_cycle/implementation/cell.py @@ -9,15 +9,12 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from .... import Explicit, ODE -from .... import master_data_model as D -from ...base import interface as B +from pycopancore.process_types import Explicit, ODE +from pycopancore.data_model import master_data_model as D +from pycopancore.model_components.base import interface as B from .. import interface as I -import numpy as np -import sympy as sp - class Cell (I.Cell): """Jobst: write docstring.""" diff --git a/pycopan_more/model_components/anderies_carbon_cycle/implementation/environment.py b/pycopan_more/model_components/anderies_carbon_cycle/implementation/environment.py index a7dcf2b..d4a89b7 100644 --- a/pycopan_more/model_components/anderies_carbon_cycle/implementation/environment.py +++ b/pycopan_more/model_components/anderies_carbon_cycle/implementation/environment.py @@ -11,8 +11,7 @@ # License: BSD 2-clause license from .. import interface as I -from ....data_model.master_data_model.dimensions_and_units import \ - gigatonnes_carbon, years, square_kilometers, kelvins +from pycopancore.data_model.master_data_model.dimensions_and_units import DimensionsAndUnits as D class Environment (I.Environment): @@ -22,24 +21,24 @@ class Environment (I.Environment): def __init__(self, *, # TODO: uncomment when adding named args behind here - ocean_atmosphere_diffusion_coefficient=0.05 / years, # Anderies + ocean_atmosphere_diffusion_coefficient=0.05 / D.years, # Anderies carbon_solubility_in_sea_water=1, # Anderies - basic_photosynthesis_productivity=26.4 / years / \ - (gigatonnes_carbon / - square_kilometers)**.5, # see Nitzbon 2016 + basic_photosynthesis_productivity=26.4 / D.years / \ + (D.gigatonnes_carbon / + D.square_kilometers)**.5, # see Nitzbon 2016 photosynthesis_sensitivity_on_atmospheric_carbon=0 \ # 1.1e6 \ - / years / (gigatonnes_carbon / square_kilometers)**.5 - / kelvins, # see Nitzbon 2016 + / D.years / (D.gigatonnes_carbon / D.square_kilometers)**.5 + / D.kelvins, # see Nitzbon 2016 terrestrial_carbon_capacity_per_area=5000 / 1.5e8 * \ - gigatonnes_carbon / square_kilometers, # ca. 2 times current value - basic_respiration_rate=0.0298 / years, # see Nitzbon 2016 + D.gigatonnes_carbon / D.square_kilometers, # ca. 2 times current value + basic_respiration_rate=0.0298 / D.years, # see Nitzbon 2016 respiration_sensitivity_on_atmospheric_carbon=0 \ # 3200 \ - / years / (gigatonnes_carbon / square_kilometers), # see Nitzbon 2016 - temperature_offset=0.2 * kelvins, # Anderies + / D.years / (D.gigatonnes_carbon / D.square_kilometers), # see Nitzbon 2016 + temperature_offset=0.2 * D.kelvins, # Anderies temperature_sensitivity_on_atmospheric_carbon=0.8 * \ - kelvins / gigatonnes_carbon, # Anderies + D.kelvins / D.gigatonnes_carbon, # Anderies scaling_factor_temperature_respiration=110, # Anderies exponent_for_increase_in_respiration_low_T=4, # Anderies exponent_for_increase_in_respiration_high_T=5, # Anderies diff --git a/pycopan_more/model_components/anderies_carbon_cycle/implementation/social_system.py b/pycopan_more/model_components/anderies_carbon_cycle/implementation/social_system.py index 442abcd..5c796ef 100644 --- a/pycopan_more/model_components/anderies_carbon_cycle/implementation/social_system.py +++ b/pycopan_more/model_components/anderies_carbon_cycle/implementation/social_system.py @@ -14,7 +14,7 @@ # License: BSD 2-clause license from .. import interface as I -#from .... import master_data_model as D +#from pycopancore.data_model import master_data_model as D class SocialSystem (I.SocialSystem): diff --git a/pycopan_more/model_components/anderies_carbon_cycle/implementation/world.py b/pycopan_more/model_components/anderies_carbon_cycle/implementation/world.py index d6f750f..fa863dc 100644 --- a/pycopan_more/model_components/anderies_carbon_cycle/implementation/world.py +++ b/pycopan_more/model_components/anderies_carbon_cycle/implementation/world.py @@ -9,10 +9,10 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from .... import Explicit, ODE +from pycopancore.process_types import Explicit, ODE from .. import interface as I -from ...base import interface as B -from .... import master_data_model as D +from pycopancore.model_components.base import interface as B +from pycopancore.data_model import master_data_model as D import sympy as sp diff --git a/pycopan_more/model_components/anderies_carbon_cycle/interface.py b/pycopan_more/model_components/anderies_carbon_cycle/interface.py index b0a232c..9583b93 100644 --- a/pycopan_more/model_components/anderies_carbon_cycle/interface.py +++ b/pycopan_more/model_components/anderies_carbon_cycle/interface.py @@ -10,9 +10,9 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from ... import master_data_model as D -from ...data_model.master_data_model import ENV, MET, CUL, W, S, C, I -from ... import Variable +from pycopancore.data_model import master_data_model as D +from pycopancore.data_model.master_data_model import ENV, MET, CUL, W, S, C, I +from pycopancore.data_model import Variable class Model (object): diff --git a/pycopan_more/model_components/carbon_voters/implementation/culture.py b/pycopan_more/model_components/carbon_voters/implementation/culture.py index e209ab9..56619ff 100644 --- a/pycopan_more/model_components/carbon_voters/implementation/culture.py +++ b/pycopan_more/model_components/carbon_voters/implementation/culture.py @@ -14,8 +14,8 @@ # License: BSD 2-clause license from .. import interface as I -# from .... import master_data_model as D -from .... import Explicit +# from pycopancore.data_model import master_data_model as D +from pycopancore.process_types import Explicit import sympy as sp import random diff --git a/pycopan_more/model_components/carbon_voters/implementation/social_system.py b/pycopan_more/model_components/carbon_voters/implementation/social_system.py index 0eeeb06..ee9dffb 100644 --- a/pycopan_more/model_components/carbon_voters/implementation/social_system.py +++ b/pycopan_more/model_components/carbon_voters/implementation/social_system.py @@ -14,10 +14,8 @@ # License: BSD 2-clause license from .. import interface as I -from ...base import interface as B -# from .... import master_data_model as D -from .... import Explicit -import sympy as sp +# from pycopancore.data_model import master_data_model as D +from pycopancore.process_types import Explicit class SocialSystem (I.SocialSystem): diff --git a/pycopan_more/model_components/carbon_voters/implementation/world.py b/pycopan_more/model_components/carbon_voters/implementation/world.py index b4cd66e..b60adaf 100644 --- a/pycopan_more/model_components/carbon_voters/implementation/world.py +++ b/pycopan_more/model_components/carbon_voters/implementation/world.py @@ -14,7 +14,7 @@ # License: BSD 2-clause license from .. import interface as I -# from .... import master_data_model as D +# from pycopancore.data_model import master_data_model as D class World (I.World): diff --git a/pycopan_more/model_components/carbon_voters/interface.py b/pycopan_more/model_components/carbon_voters/interface.py index 8855de4..9aef54c 100644 --- a/pycopan_more/model_components/carbon_voters/interface.py +++ b/pycopan_more/model_components/carbon_voters/interface.py @@ -14,7 +14,7 @@ # License: BSD 2-clause license # TODO: use variables from the master data model wherever possible: -from ... import master_data_model as D +from pycopancore.data_model import master_data_model as D # TODO: uncomment and adjust of you need further variables from another # model component: # import ..BBB.interface as BBB @@ -22,7 +22,7 @@ from .. import majority_decision as md from .. import anderies_carbon_cycle as cc # TODO: uncomment and adjust only if you really need other variables: -from ... import Variable +from pycopancore.data_model import Variable class Model (object): diff --git a/pycopan_more/model_components/config.py b/pycopan_more/model_components/config.py new file mode 100644 index 0000000..2064758 --- /dev/null +++ b/pycopan_more/model_components/config.py @@ -0,0 +1,17 @@ +"""Config module for configuring generic components such as generic_imitation. +In any model definition using a component that needs configuration, +first import this module and set its attributes +before (!) importing the respective component(s). + +Example: + +from ..model_components import config +from ...model_components import environmental_awareness as aware +... +config.generic_imitation = {'variables': [aware.interface.Individual.is_environmentally_friendly]} +from ...model_components import generic_imitation as imi +... +""" + +variables = None +"""list of Variable objects that will be imitated in the model""" \ No newline at end of file diff --git a/pycopan_more/model_components/copan_global_like_carbon_cycle/implementation/cell.py b/pycopan_more/model_components/copan_global_like_carbon_cycle/implementation/cell.py index 699ad55..beb4c2c 100644 --- a/pycopan_more/model_components/copan_global_like_carbon_cycle/implementation/cell.py +++ b/pycopan_more/model_components/copan_global_like_carbon_cycle/implementation/cell.py @@ -10,8 +10,8 @@ # License: BSD 2-clause license -from .... import Explicit, ODE -from ...base import interface as B +from pycopancore.process_types import Explicit, ODE +from pycopancore.model_components.base import interface as B from .. import interface as I diff --git a/pycopan_more/model_components/copan_global_like_carbon_cycle/implementation/world.py b/pycopan_more/model_components/copan_global_like_carbon_cycle/implementation/world.py index 5db56dd..12cd254 100644 --- a/pycopan_more/model_components/copan_global_like_carbon_cycle/implementation/world.py +++ b/pycopan_more/model_components/copan_global_like_carbon_cycle/implementation/world.py @@ -9,10 +9,9 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from .... import Explicit, ODE +from pycopancore.process_types import Explicit, ODE from .. import interface as I -from ...base import interface as B -from .... import master_data_model as D +from pycopancore.model_components.base import interface as B class World (I.World): diff --git a/pycopan_more/model_components/copan_global_like_carbon_cycle/interface.py b/pycopan_more/model_components/copan_global_like_carbon_cycle/interface.py index 3cf7a57..a8ddbfe 100644 --- a/pycopan_more/model_components/copan_global_like_carbon_cycle/interface.py +++ b/pycopan_more/model_components/copan_global_like_carbon_cycle/interface.py @@ -9,9 +9,9 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from ... import master_data_model as D -from ...data_model.master_data_model import ENV, W, C -from ... import Variable +from pycopancore.data_model import master_data_model as D +from pycopancore.data_model.master_data_model import ENV, W, C +from pycopancore.data_model import Variable class Model (object): diff --git a/pycopan_more/model_components/copan_global_like_economic_growth/implementation/social_system.py b/pycopan_more/model_components/copan_global_like_economic_growth/implementation/social_system.py index 97cd419..6e31b8d 100644 --- a/pycopan_more/model_components/copan_global_like_economic_growth/implementation/social_system.py +++ b/pycopan_more/model_components/copan_global_like_economic_growth/implementation/social_system.py @@ -10,8 +10,8 @@ # License: BSD 2-clause license from .. import interface as I -from .... import Explicit, ODE -from ...base import interface as B +from pycopancore.process_types import Explicit, ODE +from pycopancore.model_components.base import interface as B class SocialSystem (I.SocialSystem): diff --git a/pycopan_more/model_components/copan_global_like_economic_growth/implementation/world.py b/pycopan_more/model_components/copan_global_like_economic_growth/implementation/world.py index 8161a9f..9b066d0 100644 --- a/pycopan_more/model_components/copan_global_like_economic_growth/implementation/world.py +++ b/pycopan_more/model_components/copan_global_like_economic_growth/implementation/world.py @@ -9,9 +9,9 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from .... import Explicit +from pycopancore.process_types import Explicit from .. import interface as I -from ...base import interface as B +from pycopancore.model_components.base import interface as B class World (I.World): diff --git a/pycopan_more/model_components/copan_global_like_economic_growth/interface.py b/pycopan_more/model_components/copan_global_like_economic_growth/interface.py index c5d495d..15e34f0 100644 --- a/pycopan_more/model_components/copan_global_like_economic_growth/interface.py +++ b/pycopan_more/model_components/copan_global_like_economic_growth/interface.py @@ -9,8 +9,8 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from ... import master_data_model as D -from ...data_model.master_data_model import MET, S, W +from pycopancore.data_model import master_data_model as D +from pycopancore.data_model.master_data_model import MET, S, W class Model (object): diff --git a/pycopan_more/model_components/copan_global_like_population_growth/implementation/social_system.py b/pycopan_more/model_components/copan_global_like_population_growth/implementation/social_system.py index 8f4ee6b..5829cab 100644 --- a/pycopan_more/model_components/copan_global_like_population_growth/implementation/social_system.py +++ b/pycopan_more/model_components/copan_global_like_population_growth/implementation/social_system.py @@ -12,9 +12,9 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from .... import Explicit, ODE -from ...base import interface as B -from .... import master_data_model as D +from pycopancore.process_types import Explicit, ODE +from pycopancore.model_components.base import interface as B +from pycopancore.data_model import master_data_model as D from .. import interface as I diff --git a/pycopan_more/model_components/copan_global_like_population_growth/interface.py b/pycopan_more/model_components/copan_global_like_population_growth/interface.py index 14a35cb..c25f551 100644 --- a/pycopan_more/model_components/copan_global_like_population_growth/interface.py +++ b/pycopan_more/model_components/copan_global_like_population_growth/interface.py @@ -11,9 +11,9 @@ # License: BSD 2-clause license # TODO: use variables from the master data model wherever possible: -from ... import master_data_model as D -from ...data_model.master_data_model import MET, S -from ... import Variable +from pycopancore.data_model import master_data_model as D +from pycopancore.data_model.master_data_model import MET, S +from pycopancore.data_model import Variable class Model (object): diff --git a/pycopan_more/model_components/copan_global_like_production/implementation/cell.py b/pycopan_more/model_components/copan_global_like_production/implementation/cell.py index 261ecc8..33a9e7b 100644 --- a/pycopan_more/model_components/copan_global_like_production/implementation/cell.py +++ b/pycopan_more/model_components/copan_global_like_production/implementation/cell.py @@ -9,10 +9,11 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from .... import Explicit, ITE -from .... import master_data_model as D +from pycopancore.process_types import Explicit +from pycopancore.util import ITE +from pycopancore.data_model import master_data_model as D from .. import interface as I -from ...base import interface as B +from pycopancore.model_components.base import interface as B from sympy import Min, Max diff --git a/pycopan_more/model_components/copan_global_like_production/implementation/social_system.py b/pycopan_more/model_components/copan_global_like_production/implementation/social_system.py index fee3a19..d0c2b80 100644 --- a/pycopan_more/model_components/copan_global_like_production/implementation/social_system.py +++ b/pycopan_more/model_components/copan_global_like_production/implementation/social_system.py @@ -12,9 +12,9 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from .... import Explicit, ODE +from pycopancore.process_types import Explicit, ODE from .. import interface as I -from ...base import interface as B +from pycopancore.model_components.base import interface as B import numpy as np diff --git a/pycopan_more/model_components/copan_global_like_production/interface.py b/pycopan_more/model_components/copan_global_like_production/interface.py index 7aa6995..1a7a5cd 100644 --- a/pycopan_more/model_components/copan_global_like_production/interface.py +++ b/pycopan_more/model_components/copan_global_like_production/interface.py @@ -9,9 +9,9 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from ... import master_data_model as D -from ...data_model.master_data_model import MET, W, S, C -from ... import Variable +from pycopancore.data_model import master_data_model as D +from pycopancore.data_model.master_data_model import MET, W, S, C +from pycopancore.data_model import Variable class Model (object): diff --git a/pycopan_more/model_components/environmental_awareness/implementation/cell.py b/pycopan_more/model_components/environmental_awareness/implementation/cell.py index e461b72..c78bd59 100644 --- a/pycopan_more/model_components/environmental_awareness/implementation/cell.py +++ b/pycopan_more/model_components/environmental_awareness/implementation/cell.py @@ -12,9 +12,10 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from .... import Explicit, ODE, ITE +from pycopancore.process_types import Explicit, ODE +from pycopancore.util import ITE from .. import interface as I -from ...base import interface as B +from pycopancore.model_components.base import interface as B class Cell (I.Cell): """Cell entity type mixin implementation class.""" diff --git a/pycopan_more/model_components/environmental_awareness/implementation/culture.py b/pycopan_more/model_components/environmental_awareness/implementation/culture.py index feb9fbf..f1909c8 100644 --- a/pycopan_more/model_components/environmental_awareness/implementation/culture.py +++ b/pycopan_more/model_components/environmental_awareness/implementation/culture.py @@ -9,9 +9,9 @@ # URL: # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from .... import Event +from pycopancore.process_types import Event from .. import interface as I -from ...base import interface as B +from pycopancore.model_components.base import interface as B from numpy import inf from numpy.random import exponential, uniform diff --git a/pycopan_more/model_components/environmental_awareness/implementation/social_system.py b/pycopan_more/model_components/environmental_awareness/implementation/social_system.py index 084b461..5c69529 100644 --- a/pycopan_more/model_components/environmental_awareness/implementation/social_system.py +++ b/pycopan_more/model_components/environmental_awareness/implementation/social_system.py @@ -12,11 +12,12 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from .... import Explicit, ITE +from pycopancore.process_types import Explicit +from pycopancore.util import ITE from .. import interface as I -from ...base import interface as B +from pycopancore.model_components.base import interface as B -# from .... import master_data_model as D +# from pycopancore.data_model import master_data_model as D class SocialSystem (I.SocialSystem): diff --git a/pycopan_more/model_components/environmental_awareness/interface.py b/pycopan_more/model_components/environmental_awareness/interface.py index b61cbb5..158fae1 100644 --- a/pycopan_more/model_components/environmental_awareness/interface.py +++ b/pycopan_more/model_components/environmental_awareness/interface.py @@ -11,9 +11,9 @@ # License: BSD 2-clause license # TODO: use variables from the master data model wherever possible: -from ... import master_data_model as D -from ...data_model.master_data_model import CUL, I, S, C -from ... import Variable +from pycopancore.data_model import master_data_model as D +from pycopancore.data_model.master_data_model import CUL, I, S, C +from pycopancore.data_model import Variable class Model (object): diff --git a/pycopan_more/model_components/exodus/implementation/cell.py b/pycopan_more/model_components/exodus/implementation/cell.py index 4392798..65d317a 100644 --- a/pycopan_more/model_components/exodus/implementation/cell.py +++ b/pycopan_more/model_components/exodus/implementation/cell.py @@ -14,7 +14,7 @@ # License: BSD 2-clause license from .. import interface as I -# from .... import master_data_model as D +# from pycopancore.data_model import master_data_model as D class Cell (I.Cell): diff --git a/pycopan_more/model_components/exodus/implementation/culture.py b/pycopan_more/model_components/exodus/implementation/culture.py index c13b9f5..1a2aeff 100644 --- a/pycopan_more/model_components/exodus/implementation/culture.py +++ b/pycopan_more/model_components/exodus/implementation/culture.py @@ -15,8 +15,8 @@ from .. import interface as I from pycopancore.model_components.base import interface as B -# from .... import master_data_model as D -from pycopancore import Explicit, Step +# from pycopancore.data_model import master_data_model as D +from pycopancore.process_types import Explicit, Step import networkx as nx import community diff --git a/pycopan_more/model_components/exodus/implementation/individual.py b/pycopan_more/model_components/exodus/implementation/individual.py index 231f66c..e9ef032 100644 --- a/pycopan_more/model_components/exodus/implementation/individual.py +++ b/pycopan_more/model_components/exodus/implementation/individual.py @@ -15,7 +15,7 @@ from .. import interface as I from pycopancore.model_components.base import interface as B -from pycopancore import Event, Explicit +from pycopancore.process_types import Event, Explicit import math import random import numpy as np @@ -119,7 +119,7 @@ def social_update(self, unused_t): migrated = True # Network is fully connected: - chosen_one = random.choice(self.culture.acquaintance_network.nodes()) + chosen_one = random.choice(list(self.culture.acquaintance_network.nodes())) # Add event to social systems migration counter: self.social_system.migration_counter[0] += 1 self.social_system.migration_counter[1].append( diff --git a/pycopan_more/model_components/exodus/implementation/metabolism.py b/pycopan_more/model_components/exodus/implementation/metabolism.py index e6dfc59..3ad46b4 100644 --- a/pycopan_more/model_components/exodus/implementation/metabolism.py +++ b/pycopan_more/model_components/exodus/implementation/metabolism.py @@ -15,7 +15,7 @@ from .. import interface as I from pycopancore.model_components.base import interface as B -from pycopancore import Step, Explicit +from pycopancore.process_types import Step, Explicit from scipy import optimize import numpy as np diff --git a/pycopan_more/model_components/exodus/implementation/social_system.py b/pycopan_more/model_components/exodus/implementation/social_system.py index 88500bb..ccfe2b8 100644 --- a/pycopan_more/model_components/exodus/implementation/social_system.py +++ b/pycopan_more/model_components/exodus/implementation/social_system.py @@ -15,8 +15,8 @@ from .. import interface as I from pycopancore.model_components.base import interface as B -from pycopancore import Explicit, Step -# from .... import master_data_model as D +from pycopancore.process_types import Explicit, Step +# from pycopancore.data_model import master_data_model as D from scipy import stats import numpy as np diff --git a/pycopan_more/model_components/exodus/implementation/world.py b/pycopan_more/model_components/exodus/implementation/world.py index 5d1e31b..507b90d 100644 --- a/pycopan_more/model_components/exodus/implementation/world.py +++ b/pycopan_more/model_components/exodus/implementation/world.py @@ -16,8 +16,8 @@ from .. import interface as I from pycopancore.model_components.base import interface as B import numpy -from pycopancore import Explicit -# from .... import master_data_model as D +from pycopancore.process_types import Explicit +# from pycopancore.data_model import master_data_model as D class World (I.World): diff --git a/pycopan_more/model_components/exodus/interface.py b/pycopan_more/model_components/exodus/interface.py index 1aabc77..7b00572 100644 --- a/pycopan_more/model_components/exodus/interface.py +++ b/pycopan_more/model_components/exodus/interface.py @@ -13,8 +13,8 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from ... import master_data_model as D -from ... import Variable +from pycopancore.data_model import master_data_model as D +from pycopancore.data_model import Variable class Model (object): diff --git a/pycopan_more/model_components/exploit_social_learning/implementation/culture.py b/pycopan_more/model_components/exploit_social_learning/implementation/culture.py index 734b0cc..13bdcc0 100644 --- a/pycopan_more/model_components/exploit_social_learning/implementation/culture.py +++ b/pycopan_more/model_components/exploit_social_learning/implementation/culture.py @@ -11,7 +11,7 @@ from pycopancore.model_components.base import interface as B from .. import interface as I -from .... import Step +from pycopancore.process_types import Step import numpy as np import networkx as nx diff --git a/pycopan_more/model_components/exploit_social_learning/implementation/world.py b/pycopan_more/model_components/exploit_social_learning/implementation/world.py index 2b19b9b..6460b19 100644 --- a/pycopan_more/model_components/exploit_social_learning/implementation/world.py +++ b/pycopan_more/model_components/exploit_social_learning/implementation/world.py @@ -15,7 +15,7 @@ import numpy as np from pycopancore.model_components import abstract -from pycopancore.model_components.exploit_social_learning import interface as I +from ...exploit_social_learning import interface as I class World (I.World, abstract.World): diff --git a/pycopan_more/model_components/exploit_social_learning/interface.py b/pycopan_more/model_components/exploit_social_learning/interface.py index 1f7f28f..7058f5c 100644 --- a/pycopan_more/model_components/exploit_social_learning/interface.py +++ b/pycopan_more/model_components/exploit_social_learning/interface.py @@ -10,12 +10,12 @@ # License: BSD 2-clause license # TODO: use variables from the master data model wherever possible: -from ... import master_data_model as D +from pycopancore.data_model import master_data_model as D # TODO: uncomment and adjust of you need further variables from another # model component: # import ..BBB.interface as BBB # TODO: uncomment and adjust only if you really need other variables: -from ... import Variable +from pycopancore.data_model import Variable class Model(object): diff --git a/pycopan_more/model_components/generic_imitation/implementation/culture.py b/pycopan_more/model_components/generic_imitation/implementation/culture.py index 32b100f..c5c6fce 100644 --- a/pycopan_more/model_components/generic_imitation/implementation/culture.py +++ b/pycopan_more/model_components/generic_imitation/implementation/culture.py @@ -1,7 +1,7 @@ """Culture process taxon mixing class template. """ -from .... import profile +from profilehooks import profile """ TODO: @@ -24,7 +24,7 @@ from numpy.random import exponential, uniform, choice, shuffle from networkx import DiGraph -from .... import Event +from pycopancore.process_types import Event from ... import config from .. import interface as I diff --git a/pycopan_more/model_components/generic_imitation/interface.py b/pycopan_more/model_components/generic_imitation/interface.py index 8259246..0edfe6c 100644 --- a/pycopan_more/model_components/generic_imitation/interface.py +++ b/pycopan_more/model_components/generic_imitation/interface.py @@ -13,9 +13,9 @@ from typing import List, Dict, Union, Tuple, Any from networkx import Graph, DiGraph -from ... import master_data_model as D -from ...data_model.master_data_model import I -from ... import Variable +from pycopancore.data_model import master_data_model as D +from pycopancore.data_model.master_data_model import I +from pycopancore.data_model import Variable class Model (object): diff --git a/pycopan_more/model_components/majority_decision/implementation/culture.py b/pycopan_more/model_components/majority_decision/implementation/culture.py index b498174..8dd9c67 100644 --- a/pycopan_more/model_components/majority_decision/implementation/culture.py +++ b/pycopan_more/model_components/majority_decision/implementation/culture.py @@ -14,7 +14,7 @@ # License: BSD 2-clause license from .. import interface as I -# from .... import master_data_model as D +# from pycopancore.data_model import master_data_model as D class Culture (I.Culture): diff --git a/pycopan_more/model_components/majority_decision/implementation/individual.py b/pycopan_more/model_components/majority_decision/implementation/individual.py index b5e385a..1f53a13 100644 --- a/pycopan_more/model_components/majority_decision/implementation/individual.py +++ b/pycopan_more/model_components/majority_decision/implementation/individual.py @@ -14,7 +14,7 @@ # License: BSD 2-clause license from .. import interface as I -# from .... import master_data_model as D +# from pycopancore.data_model import master_data_model as D class Individual (I.Individual): diff --git a/pycopan_more/model_components/majority_decision/implementation/social_system.py b/pycopan_more/model_components/majority_decision/implementation/social_system.py index 35ee0ae..cf5708e 100644 --- a/pycopan_more/model_components/majority_decision/implementation/social_system.py +++ b/pycopan_more/model_components/majority_decision/implementation/social_system.py @@ -14,9 +14,9 @@ # License: BSD 2-clause license from .. import interface as I -# from .... import master_data_model as D +# from pycopancore.data_model import master_data_model as D -from .... import Explicit +from pycopancore.process_types import Explicit import operator diff --git a/pycopan_more/model_components/majority_decision/interface.py b/pycopan_more/model_components/majority_decision/interface.py index d295f6c..ca0591a 100644 --- a/pycopan_more/model_components/majority_decision/interface.py +++ b/pycopan_more/model_components/majority_decision/interface.py @@ -14,13 +14,13 @@ # License: BSD 2-clause license # TODO: use variables from the master data model wherever possible: -from ... import master_data_model as D +from pycopancore.data_model import master_data_model as D # TODO: uncomment and adjust of you need further variables from another # model component: # import ..BBB.interface as BBB from .. import adaptive_voter_opinion_formation as avof # TODO: uncomment and adjust only if you really need other variables: -from ... import Variable +from pycopancore.data_model import Variable class Model (object): diff --git a/pycopan_more/model_components/most_simple_vegetation/implementation/cell.py b/pycopan_more/model_components/most_simple_vegetation/implementation/cell.py index 5b8a538..d49126b 100644 --- a/pycopan_more/model_components/most_simple_vegetation/implementation/cell.py +++ b/pycopan_more/model_components/most_simple_vegetation/implementation/cell.py @@ -9,8 +9,8 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from pycopancore import ODE -from pycopancore.model_components.simple_extraction import interface as I +from pycopancore.process_types import ODE +from ...simple_extraction import interface as I class Cell(I.Cell): diff --git a/pycopan_more/model_components/most_simple_vegetation/interface.py b/pycopan_more/model_components/most_simple_vegetation/interface.py index 7426986..f5e0677 100644 --- a/pycopan_more/model_components/most_simple_vegetation/interface.py +++ b/pycopan_more/model_components/most_simple_vegetation/interface.py @@ -10,12 +10,12 @@ # License: BSD 2-clause license # TODO: use variables from the master data model wherever possible: -# from ... import master_data_model as D +# from pycopancore.data_model import master_data_model as D # TODO: uncomment and adjust of you need further variables from another # model component: # import ..BBB.interface as BBB # TODO: uncomment and adjust only if you really need other variables: -from ... import Variable +from pycopancore.data_model import Variable class Model(object): diff --git a/pycopan_more/model_components/seven_dwarfs/implementation/cell.py b/pycopan_more/model_components/seven_dwarfs/implementation/cell.py index a15e74d..d466082 100644 --- a/pycopan_more/model_components/seven_dwarfs/implementation/cell.py +++ b/pycopan_more/model_components/seven_dwarfs/implementation/cell.py @@ -17,7 +17,7 @@ from pycopancore.process_types import Event import numpy as np -# from .... import master_data_model as D +# from pycopancore.data_model import master_data_model as D class Cell (I.Cell): diff --git a/pycopan_more/model_components/seven_dwarfs/implementation/culture.py b/pycopan_more/model_components/seven_dwarfs/implementation/culture.py index c8e2d19..15dbd5c 100644 --- a/pycopan_more/model_components/seven_dwarfs/implementation/culture.py +++ b/pycopan_more/model_components/seven_dwarfs/implementation/culture.py @@ -14,7 +14,7 @@ # License: BSD 2-clause license from .. import interface as I -# from .... import master_data_model as D +# from pycopancore.data_model import master_data_model as D class Culture (I.Culture): diff --git a/pycopan_more/model_components/seven_dwarfs/implementation/individual.py b/pycopan_more/model_components/seven_dwarfs/implementation/individual.py index 11415c8..47a7d5b 100644 --- a/pycopan_more/model_components/seven_dwarfs/implementation/individual.py +++ b/pycopan_more/model_components/seven_dwarfs/implementation/individual.py @@ -15,7 +15,7 @@ from .. import interface as I from pycopancore.model_components.base import interface as B -# from .... import master_data_model as D +# from pycopancore.data_model import master_data_model as D from pycopancore.process_types import ODE, Step, Explicit, Event import numpy as np diff --git a/pycopan_more/model_components/seven_dwarfs/implementation/social_system.py b/pycopan_more/model_components/seven_dwarfs/implementation/social_system.py index 97810bd..d37c261 100644 --- a/pycopan_more/model_components/seven_dwarfs/implementation/social_system.py +++ b/pycopan_more/model_components/seven_dwarfs/implementation/social_system.py @@ -14,7 +14,7 @@ from .. import interface as I from pycopancore.model_components.base import interface as B -# from .... import master_data_model as D +# from pycopancore.data_model import master_data_model as D from pycopancore.process_types import ODE, Step, Explicit, Event import numpy as np diff --git a/pycopan_more/model_components/seven_dwarfs/implementation/world.py b/pycopan_more/model_components/seven_dwarfs/implementation/world.py index 1de27cc..19c8189 100644 --- a/pycopan_more/model_components/seven_dwarfs/implementation/world.py +++ b/pycopan_more/model_components/seven_dwarfs/implementation/world.py @@ -14,7 +14,7 @@ # License: BSD 2-clause license from .. import interface as I -# from .... import master_data_model as D +# from pycopancore.data_model import master_data_model as D class World (I.World): diff --git a/pycopan_more/model_components/seven_dwarfs/interface.py b/pycopan_more/model_components/seven_dwarfs/interface.py index f39da64..d252f57 100644 --- a/pycopan_more/model_components/seven_dwarfs/interface.py +++ b/pycopan_more/model_components/seven_dwarfs/interface.py @@ -14,14 +14,13 @@ # License: BSD 2-clause license # TODO: use variables from the master data model wherever possible: -# from ... import master_data_model as D +# from pycopancore.data_model import master_data_model as D # TODO: uncomment and adjust of you need further variables from another # model component: # import ..BBB.interface as BBB # TODO: uncomment and adjust only if you really need other variables: from pycopancore.data_model import Variable from pycopancore.data_model import master_data_model as D -from pycopancore.data_model.master_data_model import CUL class Model (object): diff --git a/pycopan_more/model_components/simple_extraction/implementation/cell.py b/pycopan_more/model_components/simple_extraction/implementation/cell.py index 9ad1f45..be334dc 100644 --- a/pycopan_more/model_components/simple_extraction/implementation/cell.py +++ b/pycopan_more/model_components/simple_extraction/implementation/cell.py @@ -9,8 +9,8 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from pycopancore import ODE -from pycopancore.model_components.simple_extraction import interface as I +from pycopancore.process_types import ODE +from ...simple_extraction import interface as I class Cell(I.Cell): diff --git a/pycopan_more/model_components/simple_extraction/interface.py b/pycopan_more/model_components/simple_extraction/interface.py index ffb8d3c..8560feb 100644 --- a/pycopan_more/model_components/simple_extraction/interface.py +++ b/pycopan_more/model_components/simple_extraction/interface.py @@ -10,12 +10,12 @@ # License: BSD 2-clause license # TODO: use variables from the master data model wherever possible: -# from ... import master_data_model as D +# from pycopancore.data_model import master_data_model as D # TODO: uncomment and adjust of you need further variables from another # model component: from ..exploit_social_learning import Individual as ESLIndividual # TODO: uncomment and adjust only if you really need other variables: -from ... import Variable +from pycopancore.data_model import Variable class Model(object): diff --git a/pycopan_more/model_components/snowwhite/implementation/cell.py b/pycopan_more/model_components/snowwhite/implementation/cell.py index 341ce8b..3c16172 100644 --- a/pycopan_more/model_components/snowwhite/implementation/cell.py +++ b/pycopan_more/model_components/snowwhite/implementation/cell.py @@ -15,7 +15,7 @@ from pycopancore.process_types import Event import numpy as np -# from .... import master_data_model as D +# from pycopancore.data_model import master_data_model as D class Cell (I.Cell): diff --git a/pycopan_more/model_components/snowwhite/interface.py b/pycopan_more/model_components/snowwhite/interface.py index 933d106..d172aef 100644 --- a/pycopan_more/model_components/snowwhite/interface.py +++ b/pycopan_more/model_components/snowwhite/interface.py @@ -13,7 +13,7 @@ # License: MIT license # TODO: use variables from the master data model wherever possible: -# from ... import master_data_model as D +# from pycopancore.data_model import master_data_model as D # TODO: uncomment and adjust of you need further variables from another # model component: # import ..BBB.interface as BBB diff --git a/pycopan_more/model_components/social_learning_of_environmental_friendliness/implementation/culture.py b/pycopan_more/model_components/social_learning_of_environmental_friendliness/implementation/culture.py index d294d5f..ac6a32f 100644 --- a/pycopan_more/model_components/social_learning_of_environmental_friendliness/implementation/culture.py +++ b/pycopan_more/model_components/social_learning_of_environmental_friendliness/implementation/culture.py @@ -10,9 +10,9 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from .... import Event +from pycopancore.process_types import Event from .. import interface as I -from ...base import interface as B +from pycopancore.model_components.base import interface as B from numpy import inf from numpy.random import exponential, uniform diff --git a/pycopan_more/model_components/social_learning_of_environmental_friendliness/interface.py b/pycopan_more/model_components/social_learning_of_environmental_friendliness/interface.py index e34fd35..f597dd8 100644 --- a/pycopan_more/model_components/social_learning_of_environmental_friendliness/interface.py +++ b/pycopan_more/model_components/social_learning_of_environmental_friendliness/interface.py @@ -13,9 +13,9 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from ... import master_data_model as D -from ...data_model.master_data_model import CUL, I -from ... import Variable +from pycopancore.data_model import master_data_model as D +from pycopancore.data_model.master_data_model import CUL, I +from pycopancore.data_model import Variable class Model (object): diff --git a/pycopan_more/model_components/voting_on_climate_policy/implementation/social_system.py b/pycopan_more/model_components/voting_on_climate_policy/implementation/social_system.py index 24086b0..60c3e86 100644 --- a/pycopan_more/model_components/voting_on_climate_policy/implementation/social_system.py +++ b/pycopan_more/model_components/voting_on_climate_policy/implementation/social_system.py @@ -14,8 +14,8 @@ # License: BSD 2-clause license from .. import interface as I -# from .... import master_data_model as D -from .... import Event +# from pycopancore.data_model import master_data_model as D +from pycopancore.process_types import Event from numpy import array from numpy.random import uniform diff --git a/pycopan_more/model_components/voting_on_climate_policy/interface.py b/pycopan_more/model_components/voting_on_climate_policy/interface.py index cba5775..bbf487b 100644 --- a/pycopan_more/model_components/voting_on_climate_policy/interface.py +++ b/pycopan_more/model_components/voting_on_climate_policy/interface.py @@ -14,13 +14,13 @@ # License: BSD 2-clause license # TODO: use variables from the master data model wherever possible: -from ... import master_data_model as D -from ...data_model.master_data_model import S +from pycopancore.data_model import master_data_model as D +from pycopancore.data_model.master_data_model import S # TODO: uncomment and adjust of you need further variables from another # model component: # import ..BBB.interface as BBB # TODO: uncomment and adjust only if you really need other variables: -from ... import Variable +from pycopancore.data_model import Variable class Model (object): diff --git a/pycopan_more/model_components/wellbeing_driven_migration/implementation/social_system.py b/pycopan_more/model_components/wellbeing_driven_migration/implementation/social_system.py index cb246b0..e942802 100644 --- a/pycopan_more/model_components/wellbeing_driven_migration/implementation/social_system.py +++ b/pycopan_more/model_components/wellbeing_driven_migration/implementation/social_system.py @@ -9,8 +9,8 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from .... import Explicit, ODE -from ...base import interface as B +from pycopancore.process_types import Explicit, ODE +from pycopancore.model_components.base import interface as B from .. import interface as I diff --git a/pycopan_more/model_components/wellbeing_driven_migration/interface.py b/pycopan_more/model_components/wellbeing_driven_migration/interface.py index bab5039..607ea88 100644 --- a/pycopan_more/model_components/wellbeing_driven_migration/interface.py +++ b/pycopan_more/model_components/wellbeing_driven_migration/interface.py @@ -11,9 +11,9 @@ # License: BSD 2-clause license # TODO: use variables from the master data model wherever possible: -from ... import master_data_model as D -from ...data_model.master_data_model import MET, S -from ... import Variable +from pycopancore.data_model import master_data_model as D +from pycopancore.data_model.master_data_model import MET, S +from pycopancore.data_model import Variable class Model (object): diff --git a/pycopan_more/models/_testing/generic_imitation/like_example1.py b/pycopan_more/models/_testing/generic_imitation/like_example1.py index 1f894c7..1a5b259 100644 --- a/pycopan_more/models/_testing/generic_imitation/like_example1.py +++ b/pycopan_more/models/_testing/generic_imitation/like_example1.py @@ -15,7 +15,7 @@ import numpy as np -from .... import base # all models must use the base component +from pycopancore.model_components import base # all models must use the base component from ....model_components import copan_global_like_carbon_cycle \ as cc diff --git a/pycopan_more/models/_testing/generic_imitation/other_component.py b/pycopan_more/models/_testing/generic_imitation/other_component.py index b83a59c..ac15f01 100644 --- a/pycopan_more/models/_testing/generic_imitation/other_component.py +++ b/pycopan_more/models/_testing/generic_imitation/other_component.py @@ -1,5 +1,5 @@ -from .... import master_data_model as D -from .... import Variable +from pycopancore.data_model import master_data_model as D +from pycopancore.data_model import Variable # INTERFACE: diff --git a/pycopan_more/models/_testing/generic_imitation/simple.py b/pycopan_more/models/_testing/generic_imitation/simple.py index 8643e4f..8ca536b 100755 --- a/pycopan_more/models/_testing/generic_imitation/simple.py +++ b/pycopan_more/models/_testing/generic_imitation/simple.py @@ -1,6 +1,6 @@ import numpy as np -from .... import base # all models must use the base component +from pycopancore.model_components import base # all models must use the base component from . import other_component as other diff --git a/pycopan_more/models/_testing/lpjml/__init__.py b/pycopan_more/models/_testing/lpjml/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/pycopan_more/models/_testing/lpjml/lpjml_dummy.py b/pycopan_more/models/_testing/lpjml/lpjml_dummy.py deleted file mode 100755 index f36dc13..0000000 --- a/pycopan_more/models/_testing/lpjml/lpjml_dummy.py +++ /dev/null @@ -1,70 +0,0 @@ -"""Dummy model for LPJmL coupling""" - -# This file is part of pycopancore. -# -# Copyright (C) 2022 by COPAN team at Potsdam Institute for Climate -# Impact Research -# -# URL: - -# all models must use the base component -from .... import base -from ....model_components import lpjml as lpj -from . import other_component as other - - -# entity types: - -class World(base.World): - """World entity type.""" - pass - -class SocialSystem(base.SocialSystem): - """SocialSystem entity type.""" - pass - -class Cell(lpj.Cell, - other.Cell, - base.Cell): - """Cell entity type.""" - pass - -class Individual(base.Individual): - """Individual entity type.""" - pass - - -# process taxa: - -class Environment(lpj.Environment, - base.Environment): - """Environment process taxon.""" - pass - -class Metabolism(other.Metabolism, - base.Metabolism): - """Metabolism process taxon.""" - pass - -class Culture(base.Culture): - """Culture process taxon.""" - pass - - -# Model class: - -class Model(lpj.Model, - other.Model, - base.Model): - """Class representing the whole model.""" - - name = "Dummy model to test LPJmL coupling" - """Name of the model""" - description = "Couples LPJmL component to some other component" - """Longer description""" - - entity_types = [World, SocialSystem, Cell, Individual] - """List of entity types used in the model""" - - process_taxa = [Environment, Metabolism, Culture] - """List of process taxa used in the model""" diff --git a/pycopan_more/models/_testing/lpjml/other_component.py b/pycopan_more/models/_testing/lpjml/other_component.py deleted file mode 100755 index d2727ec..0000000 --- a/pycopan_more/models/_testing/lpjml/other_component.py +++ /dev/null @@ -1,89 +0,0 @@ -"""Other model component to test LPJmL coupling""" - -# This file is part of pycopancore. -# -# Copyright (C) 2022 by COPAN team at Potsdam Institute for Climate -# Impact Research -# -# URL: - -from .... import master_data_model as D -from ....model_components.lpjml import interface as L -from ....model_components.base import interface as B -from .... import Variable -from .... import Event - -import numpy as np -from numpy.random import exponential, uniform - -# INTERFACE - -class ICell (object): - # landuse = L.Cell.landuse - # TODO is with_tillage really to be found in L.Cell? - with_tillage = L.Cell.with_tillage - cftfrac = L.Cell.cftfrac - -class IMetabolism (object): - # TODO check which rate is more fitting: once a year or multiple? - # landuse_update_rate = Variable( - # "landuse update rate", - # """average number of time points per time where some cells - # update their landuse""", - # unit = D.years**(-1), - # default = 5 / D.years, lower_bound = 0) - landuse_update_rate = Variable( - "landuse update rate", - """average number of time points per time where some cells - update their landuse""", - unit = D.unity, - default = 1) - landuse_update_prob = Variable( - "fishing effort update probability", - """probability that an individual updates their fishing effort at - an update time point""", - unit = D.unity, - default = 1/2, lower_bound = 0, upper_bound = 1) - - -class IModel (object): - name = "other component" - description = "only for testing lpjml coupling" - requires = [] - -class interface: - Cell = ICell - Metabolism = IMetabolism - Model = IModel - -# IMPLEMENTATION: - -class Cell (ICell): - - def update_landuse(self, unused_t): - # self.landuse = np.ones((1, 64)) - self.with_tillage = np.ones((1, 1)) - processes = [] - -class Metabolism (IMetabolism): - def next_landuse_update_time(self, t): - return t + exponential(1 / self.landuse_update_rate) - - - def update_landuse(self, unused_t): - for w in self.worlds: - for c in w.cells: - if uniform() < self.landuse_update_prob: - c.update_landuse(unused_t) - - processes = [ - Event("update landuse", - # [B.Metabolism.worlds.cells.landuse], - [B.Metabolism.worlds.cells.with_tillage], - ["time", - next_landuse_update_time, - update_landuse])] - -class Model (IModel): - entity_types = [Cell] - process_taxa = [Metabolism] diff --git a/pycopan_more/models/adaptive_voter_model.py b/pycopan_more/models/adaptive_voter_model.py index 3af4ed6..f273fdc 100644 --- a/pycopan_more/models/adaptive_voter_model.py +++ b/pycopan_more/models/adaptive_voter_model.py @@ -15,7 +15,7 @@ # Imports # -from .. import base # all models must use the base component +from pycopancore.model_components import base # all models must use the base component from ..model_components import adaptive_voter_opinion_formation as avof from ..model_components import majority_decision as md diff --git a/pycopan_more/models/base_and_dummy.py b/pycopan_more/models/base_and_dummy.py deleted file mode 100644 index 466f09f..0000000 --- a/pycopan_more/models/base_and_dummy.py +++ /dev/null @@ -1,80 +0,0 @@ -"""Dummy model to create model modules.""" - -# This file is part of pycopancore. -# -# Copyright (C) 2016-2017 by COPAN team at Potsdam Institute for Climate -# Impact Research -# -# URL: -# Contact: core@pik-potsdam.de -# License: BSD 2-clause license - -# -# Imports -# - -import pycopancore.model_components.base as base -import pycopancore.model_components.dummy as dummy - -# -# Entity Types -# - - -class World(base.World): - """Class to mix all World_mixins to create World clas.""" - - pass - - -class Cell(dummy.Cell, base.Cell): - """Class to mix all Cell_mixins to create Cell class.""" - - pass - - -class Individual(base.Individual): - """Class to mix all Individual_mixins to create Individual class.""" - - pass - - -class SocialSystem(base.SocialSystem): - """Class to mix all SocialSystem_mixins to create SocialSystem class.""" - - pass - -# -# Dynamics -# - - -class Culture(base.Culture): - """Class to mix all Culture_mixins to create Culture class.""" - - pass - - -class Metabolism(base.Metabolism): - """Class to mix all Metabolism_mixins to create Metabolism class.""" - - pass - - -class Environment(base.Environment): - """Class to mix all Environment_mixins to create Environment class.""" - - pass - -# -# Models -# - - -class Model(dummy.Model, base.Model): - """Class to mix all Model_mixins to create Model class.""" - - name = "This model's name" - description = "Description of the model" - entity_types = [Cell, Individual, SocialSystem, World] - process_taxa = [Culture, Metabolism, Environment] diff --git a/pycopan_more/models/carbon_voters_anderies_model.py b/pycopan_more/models/carbon_voters_anderies_model.py index ba27f6a..b9ddecf 100644 --- a/pycopan_more/models/carbon_voters_anderies_model.py +++ b/pycopan_more/models/carbon_voters_anderies_model.py @@ -13,7 +13,7 @@ # Imports # -from .. import base # all models must use the base component +from pycopancore.model_components import base # all models must use the base component from ..model_components import adaptive_voter_opinion_formation as avof from ..model_components import majority_decision as md diff --git a/pycopan_more/models/coccon/carboncycle.py b/pycopan_more/models/coccon/carboncycle.py index ba9ff79..eca387a 100644 --- a/pycopan_more/models/coccon/carboncycle.py +++ b/pycopan_more/models/coccon/carboncycle.py @@ -7,7 +7,7 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from ... import base # all models must use the base component +from pycopancore.model_components import base # all models must use the base component from ...model_components import copan_global_like_carbon_cycle \ as cc diff --git a/pycopan_more/models/coccon/full.py b/pycopan_more/models/coccon/full.py index e2e3db6..31bddb1 100644 --- a/pycopan_more/models/coccon/full.py +++ b/pycopan_more/models/coccon/full.py @@ -7,7 +7,7 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from ... import base # all models must use the base component +from pycopancore.model_components import base # all models must use the base component from ...model_components import copan_global_like_carbon_cycle \ as cc diff --git a/pycopan_more/models/example1.py b/pycopan_more/models/example1.py index eba5386..52adc6c 100644 --- a/pycopan_more/models/example1.py +++ b/pycopan_more/models/example1.py @@ -13,7 +13,7 @@ # Imports # -from .. import base # all models must use the base component +from pycopancore.model_components import base # all models must use the base component from ..model_components import copan_global_like_carbon_cycle \ as cc diff --git a/pycopan_more/models/example2.py b/pycopan_more/models/example2.py index 61cf685..3b6aba1 100644 --- a/pycopan_more/models/example2.py +++ b/pycopan_more/models/example2.py @@ -13,7 +13,7 @@ # Imports # -from .. import base # all models must use the base component +from pycopancore.model_components import base # all models must use the base component from ..model_components import copan_global_like_carbon_cycle \ as cc diff --git a/pycopan_more/models/exodus.py b/pycopan_more/models/exodus.py index 29486b7..6e41d7a 100644 --- a/pycopan_more/models/exodus.py +++ b/pycopan_more/models/exodus.py @@ -9,7 +9,7 @@ # Contact: core@pik-potsdam.de # License: BSD 2-clause license -from .. import base # all models must use the base component +from pycopancore.model_components import base # all models must use the base component from ..model_components import exodus as ex diff --git a/pycopan_more/models/exploit.py b/pycopan_more/models/exploit.py index 118b641..1070153 100644 --- a/pycopan_more/models/exploit.py +++ b/pycopan_more/models/exploit.py @@ -22,9 +22,9 @@ # import pycopancore.model_components.base as base -import pycopancore.model_components.most_simple_vegetation as vegetation -import pycopancore.model_components.simple_extraction as extraction -import pycopancore.model_components.exploit_social_learning as social_learning +from ..model_components import most_simple_vegetation as vegetation +from ..model_components import simple_extraction as extraction +from ..model_components import exploit_social_learning as social_learning # # Entity Types diff --git a/pycopan_more/models/groups_seven_dwarfs.py b/pycopan_more/models/groups_seven_dwarfs.py index 6c82315..08b7f63 100644 --- a/pycopan_more/models/groups_seven_dwarfs.py +++ b/pycopan_more/models/groups_seven_dwarfs.py @@ -13,7 +13,7 @@ # Imports # -from .. import base # all models must use the base component +from pycopancore.model_components import base # all models must use the base component from ..model_components import seven_dwarfs as sd from ..model_components import snowwhite as sw diff --git a/pycopan_more/models/inseeds_social.py b/pycopan_more/models/inseeds_social.py deleted file mode 100644 index a2d3466..0000000 --- a/pycopan_more/models/inseeds_social.py +++ /dev/null @@ -1,66 +0,0 @@ -""" -Social sub-component of the InSEEDS model. -This does not inlude any communication to LPJmL via the pycoupler, but can be -regarded as a first step towards coupled runs. - -Based on the exploit model, inluding novel decision-making dynamics -on tha basis of the Theory of Planned behaviour (TPB) - -Conceptualization by Luana Schwarz, implementation based on Ronja Hotz' -Exploit model MOL CC SN, with adjustments by Luana Schwarz. - -TODO: Go through the file and adjust all parts of the code marked with the TODO -flag. Pay attention to those variables and object written in capital letters. -These are placeholders and must be adjusted as needed. For further details see -also the model development tutorial. -""" -# This file is part of pycopancore. -# -# Copyright (C) 2017 by COPAN team at Potsdam Institute for Climate -# Impact Research -# -# URL: - -# -# TODO: import all other needed model components (adjust as needed): -# -import pycopancore.model_components.base as base -import pycopancore.model_components.inseeds_farmer_management as farmer_management -import pycopancore.model_components.lpjml as lpjml - - -# TODO: list all mixin classes needed: -class World(base.World, - lpjml.World, - farmer_management.World): - """World entity type.""" - pass - - -class Cell(base.Cell, - lpjml.Cell): - """Cell entity type.""" - pass - - -class Individual(farmer_management.Individual): - """Individual entity type.""" - pass - - -class Model(lpjml.Model, - farmer_management.Model, - base.Model): - """Class representing the whole model.""" - - name = "InSEEDS Social" - description = "Subcomponent of the InSEEDS model representing only social \ - dynamics and decision-making on the basis of the TPB" - - # TODO: list all entity types you composed above: - entity_types = [World, Cell, Individual] - """List of entity types used in the model""" - - # TODO: list all entity types you composed above: - process_taxa = [] - """List of process taxa used in the model""" diff --git a/pycopan_more/models/inseeds_social_config.yaml b/pycopan_more/models/inseeds_social_config.yaml deleted file mode 100644 index c477e8a..0000000 --- a/pycopan_more/models/inseeds_social_config.yaml +++ /dev/null @@ -1,60 +0,0 @@ -# Settings for LPJmL specifically for coupling (pycoupler) -# (not covered by LPJmL's direct config) -lpjml_settings: - country_code_to_name: true - iso_country_code: true - -# Variables to be written to copan_core_data table file -output: - individual: - - "aft_id" - - "behaviour" - - "tpb" - - "pbc" - - "social_norm" - - "attitude" - - "attitude_own_land" - - "attitude_social_learning" - - "soilc" - - "cropyield" - -# Define how copan_core_data table file should be written -output_settings: - write_lon_lat: true - format: "csv" - -# Define which individual variables map with coupled LPJmL input variables -coupling_map: - behaviour: ["with_tillage"] # "residue_on_field" - -control_run: False -pioneer_share: 0.25 - -# Analogous to LPJmL pftpar, define the AFT parameters for the two different -# farmer types -aftpar: - # AFT for conservative/traditional values following farmer tending to stay - # with conventional agriculture - traditionalist: - pbc: 0.95 - weight_attitude: 0.6 - weight_yield: 0.8 - weight_soil: 0.4 - weight_norm: 0.4 - weight_social_learning: 0.4 - weight_own_land: 0.6 - # duration of waiting time before switching to another strategy - strategy_switch_duration: 10 # years - - # AFT for pioneer farmer who more likely tends to switch to new (promising) - # regenerative agriculture practices - pioneer: - pbc: 0.75 - weight_attitude: 0.8 - weight_yield: 0.4 - weight_soil: 0.8 - weight_norm: 0.2 - weight_social_learning: 0.6 - weight_own_land: 0.4 - # duration of waiting time before switching to another strategy - strategy_switch_duration: 10 # years diff --git a/pycopan_more/models/only_copan_global_like_carbon_cycle.py b/pycopan_more/models/only_copan_global_like_carbon_cycle.py index cd7dcfb..1447118 100644 --- a/pycopan_more/models/only_copan_global_like_carbon_cycle.py +++ b/pycopan_more/models/only_copan_global_like_carbon_cycle.py @@ -13,7 +13,7 @@ # Imports # -from .. import base # all models must use the base component +from pycopancore.model_components import base # all models must use the base component from ..model_components import copan_global_like_carbon_cycle \ as cc diff --git a/pycopan_more/models/our_model.py b/pycopan_more/models/our_model.py index 72bea62..83cb24b 100644 --- a/pycopan_more/models/our_model.py +++ b/pycopan_more/models/our_model.py @@ -13,7 +13,7 @@ # Imports # -from .. import base # all models must use the base component +from pycopancore.model_components import base # all models must use the base component # from ..model_components import copan_global_like_carbon_cycle \ # as cc from ..model_components import anderies_carbon_cycle \ diff --git a/pycopan_more/models/seven_dwarfs.py b/pycopan_more/models/seven_dwarfs.py index c96989b..21f1f04 100644 --- a/pycopan_more/models/seven_dwarfs.py +++ b/pycopan_more/models/seven_dwarfs.py @@ -16,8 +16,8 @@ # all models must use the base component from pycopancore.model_components import base -from pycopancore.model_components import seven_dwarfs as sd -from pycopancore.model_components import snowwhite as sw +from ..model_components import seven_dwarfs as sd +from ..model_components import snowwhite as sw # entity types: diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b3e4ee1 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,37 @@ +[project] +name = "pycopan-more" +version = "0.1.0" +description = "Model and model component implementations as well as studies using the copan:CORE World-Earth modelling framework" +readme = "README.md" +requires-python = ">=3.14" +authors = [ + {name = "COPAN team @ PIK", email = "core@pik-potsdam.de"} +] +license = "BSD-2-Clause" +license-files = ["LICENSE"] +dependencies = [ + "numpy>=1.11.0", + "scipy>=0.17.0", + "sympy>=1.0", + "python-louvain>=0.9", + "profilehooks", + "pytest-cov>=2.5.1", + "numba", + "pycopancore @ git+https://github.com/pik-copan/pycopancore.git", + "matplotlib>=3.11.0", + "plotly>=6.8.0", + "networkx>=3.6.1", +] + +[tool.setuptools.packages.find] +include = ["pycopan_more"] + +[project.urls] +Repository = "https://github.com/pik-copan/pycopanmodels" + +[project.optional-dependencies] +dev = [ + "pylama", + "pylama_pylint", + "pylint" +] diff --git a/setup.py b/setup.py deleted file mode 100644 index 27767c5..0000000 --- a/setup.py +++ /dev/null @@ -1,43 +0,0 @@ -"""This is setup.py of pycopancore""" - -# This file is part of pycopancore. -# -# Copyright (C) 2016-2017 by COPAN team at Potsdam Institute for Climate -# Impact Research -# -# URL: -# Contact: core@pik-potsdam.de -# License: BSD 2-clause license - -from setuptools import setup, find_packages - -# for developers: recommended way of installing is to run in this directory -# pip install -e . -# This creates a link insteaed of copying the files, so modifications in this directory are modifications in the installed package. - -setup(name="pycopan-more", - version="0.1.0", - description="Model and model component implementations as well as studies using the copan:CORE World-Earth modelling framework", - url="https://github.com/pik-copan/pycopancore", - author="COPAN team @ PIK", - author_email="", - license="BSD-2-Clause", - packages=find_packages(), #["pycopancore"], - install_requires=[ - "numpy>=1.11.0", - "scipy>=0.17.0", - "sympy>=1.0", - # "blist>=1.3.6", - "python-louvain>=0.9", - "profilehooks", - "pytest>=4.6", - "pylama", - "pylint", - "pytest-cov>=2.5.1", - "pylama_pylint", - "numba", - "pycopancore @ git+https://github.com/pik-copan/pycopancore.git" - ], - zip_safe=False # see http://stackoverflow.com/questions/15869473/what-is-the-advantage-of-setting-zip-safe-to-true-when-packaging-a-python-projec - ) - diff --git a/studies/_testing/generic_imitation_simple.py b/studies/_testing/generic_imitation_simple.py index a6c0dd4..67164bd 100755 --- a/studies/_testing/generic_imitation_simple.py +++ b/studies/_testing/generic_imitation_simple.py @@ -1,6 +1,6 @@ """Script to run example1 model.""" -from pycopancore import config +from pycopan_more.model_components import config config.profile = False from time import time diff --git a/studies/coccon_tutorial.py b/studies/coccon_tutorial.py index 7fcf0d9..be055a6 100755 --- a/studies/coccon_tutorial.py +++ b/studies/coccon_tutorial.py @@ -13,10 +13,10 @@ from numpy import random, array, average, exp from pylab import show, subplots -from pycopancore import master_data_model as D +from pycopancore.data_model import master_data_model as D from pycopancore.runners import Runner -import pycopancore.models.coccon.full as M +from pycopan_more.models.coccon import full as M # first thing: set seed so that each execution must return same thing: diff --git a/studies/jobst2leander.py b/studies/jobst2leander.py index 7ebf5d6..a1e4436 100644 --- a/studies/jobst2leander.py +++ b/studies/jobst2leander.py @@ -6,8 +6,8 @@ from numpy import random, array import numpy as np -import pycopancore.models.example2 as M -from pycopancore import master_data_model as D +from pycopan_more.models import example2 as M +from pycopancore.data_model import master_data_model as D from pycopancore.runners import Runner from pylab import plot, gca, show, figure, subplot, gca, semilogy, legend diff --git a/studies/run_adaptive_voter_model.py b/studies/run_adaptive_voter_model.py index c271908..9999835 100755 --- a/studies/run_adaptive_voter_model.py +++ b/studies/run_adaptive_voter_model.py @@ -15,7 +15,7 @@ # import networkx as nx import numpy as np # import sys -import pycopancore.models.adaptive_voter_model as M +from pycopan_more.models import adaptive_voter_model as M # import pycopancore.models.only_copan_global_like_carbon_cycle as M # from pycopancore import master_data_model as D from pycopancore.runners import Runner diff --git a/studies/run_carbon_voters_anderies.py b/studies/run_carbon_voters_anderies.py index 96d5c60..0c7631b 100755 --- a/studies/run_carbon_voters_anderies.py +++ b/studies/run_carbon_voters_anderies.py @@ -16,9 +16,9 @@ # import networkx as nx import numpy as np # import sys -import pycopancore.models.carbon_voters_anderies_model as M +from pycopan_more.models import carbon_voters_anderies_model as M # import pycopancore.models.only_copan_global_like_carbon_cycle as M -from pycopancore import master_data_model as D +from pycopancore.data_model import master_data_model as D from pycopancore.runners import Runner # import plotly.plotly as py diff --git a/studies/run_core_lpjml.py b/studies/run_core_lpjml.py deleted file mode 100755 index 6234323..0000000 --- a/studies/run_core_lpjml.py +++ /dev/null @@ -1,142 +0,0 @@ -"""Test run script for LPJmL coupling""" - -# This file is part of pycopancore. -# -# Copyright (C) 2022 by COPAN team at Potsdam Institute for Climate -# Impact Research -# -# URL: - -import pycopancore.models._testing.lpjml.lpjml_dummy as M - -# standard runner for simulating any model: -from pycopancore.runners.runner import Runner - -from pycopancore import master_data_model as D # to be able to specify variables with physical units - -import numpy as np # which is usually needed -from numpy.random import choice, uniform # to generate random initial conditions - -import pylab as plt # to plot stuff - -# instantiate the model and have it analyse its own structure: -model = M.Model() - -print("te") - -# TODO: initial coupling - -#include config of LPJmL (maybe in own .py) -from pycoupler.coupler import Coupler -from pycoupler.data import supply_inputs, preprocess_inputs - - -# paths -# TODO add other requirements for pycoupler -model_location = "/home/lschwarz/kopplung" -base_path = "/p/projects/copan/users/lschwarz/lpjml/data" -model_path = f"{model_location}/LPJmL_internal" -config_historic_fn = f"{base_path}/config_historic.json" -config_coupled_fn = f"{base_path}/config_coupled.json" - -# coupled simulation years -start_year = 1981 -end_year = 2005 -sim_years = range(start_year, end_year+1) - -# initiate coupler after run_lpjml on LOGIN NODE 1 -coupler = Coupler(config_file=config_coupled_fn) - -# get and process initial inputs -inputs = supply_inputs(config_file=config_coupled_fn, - historic_config_file=config_historic_fn, - input_path=f"{base_path}/input", - model_path=model_path, - start_year=start_year, end_year=start_year) -input_data = preprocess_inputs(inputs, grid=coupler.grid, time=start_year) - -# input_data["with_tillage"] = input_data["with_tillage"].astype("int32") - - - -# simulation parameters: - -# coupled simulation years -# years = range(1981, 2006) -# # The following could be your model/program/script -# for year in years: -# # send input data to lpjml -# print(f"year: {year}") -# coupler.send_inputs(input_data, year) -# # read output data -# outputs = coupler.read_outputs(year) -# print(outputs) -# # generate some results based on lpjml outputs -# # .... -# coupler.close_channel() - - -delta_t = 1 # desired temporal resolution of the resulting output. - - - -# test_dict_in = {"landuse": np.zeros((1, 64)),"fertilizer_nr": np.zeros((1, 32))} -# test_dict_out = {"cftfrac": np.zeros((1, 32)),"pft_harvestc": np.zeros((1, 32)),"pft_harvestn": np.zeros((1, 32))} - - -# adjust reading and writing as in Jannes' test script -# erst mal benötigt als pre-struktur, kommt dann quasi weg, wenn lpjml output da ist -# fkt die output auf hohem level als argument entgegennimmt -test_dict_in = {"with_tillage": np.zeros((1, 1), dtype=int)} -test_dict_out = {"cftfrac": np.zeros((1, 32)), "pft_harvestc": np.zeros((1, 32))} - -landuse_update_rate = 10 -landuse_update_prob = 1. - - -dt = 1 # desired temporal resolution of the resulting output. - - -# instantiate process taxa: -env = M.Environment( - delta_t=delta_t, # dt should be given to environment probably - start_year=start_year, # our starting point - in_dict=test_dict_in, - out_dict=test_dict_out, - old_out_dict=test_dict_out, - coupler=coupler - ) -met = M.Metabolism( - landuse_update_rate=landuse_update_rate, - landuse_update_prob=landuse_update_prob - ) -cul = M.Culture( - ) - -# generate entities: - -world = M.World( - environment = env, - metabolism = met, - culture = cul, - ) -soc = M.SocialSystem(world = world) -cell = M.Cell( - social_system = soc, - lpjml_grid_cell_ids = [0], - # landuse = test_dict_in["landuse"][0] - with_tillage = test_dict_in["with_tillage"][0], - ) -ind = M.Individual(cell = cell) - -# Run the model -# - -runner = Runner(model=model) -traj = runner.run(t_0=start_year, t_1=end_year, dt=dt) - -# TODO: Add some further analysis such as plotting or saving -# plt.plot(traj['t'], traj[M.SocialSystem.population][socs[0]]) -# plt.show() - -coupler.close_channel() diff --git a/studies/run_example1.py b/studies/run_example1.py index 1b3b431..0a02a1b 100755 --- a/studies/run_example1.py +++ b/studies/run_example1.py @@ -4,8 +4,8 @@ from numpy import random, array import numpy as np -import pycopancore.models.example1 as M -from pycopancore import master_data_model as D +from pycopan_more.models import example1 as M +from pycopancore.data_model import master_data_model as D from pycopancore.runners import Runner import pycopancore as pcc diff --git a/studies/run_example2.py b/studies/run_example2.py index af0219c..ecf056c 100755 --- a/studies/run_example2.py +++ b/studies/run_example2.py @@ -4,8 +4,8 @@ from numpy import random, array import numpy as np -import pycopancore.models.example2 as M -from pycopancore import master_data_model as D +from pycopan_more.models import example2 as M +from pycopancore.data_model import master_data_model as D from pycopancore.runners import Runner from pylab import plot, gca, show, figure, subplot, gca, semilogy, legend diff --git a/studies/run_example2_mw.py b/studies/run_example2_mw.py index a5c2dd2..3d78cb1 100755 --- a/studies/run_example2_mw.py +++ b/studies/run_example2_mw.py @@ -4,8 +4,8 @@ from numpy import random, array import numpy as np -import pycopancore.models.example2 as M -from pycopancore import master_data_model as D +from pycopan_more.models import example2 as M +from pycopancore.data_model import master_data_model as D from pycopancore.runners import Runner from pylab import plot, gca, show, figure, subplot, gca, semilogy, legend diff --git a/studies/run_example2_varying_learning_rate.py b/studies/run_example2_varying_learning_rate.py index 9842518..384c122 100644 --- a/studies/run_example2_varying_learning_rate.py +++ b/studies/run_example2_varying_learning_rate.py @@ -4,8 +4,8 @@ from numpy import random, array import numpy as np -import pycopancore.models.example2 as M -from pycopancore import master_data_model as D +from pycopan_more.models import example2 as M +from pycopancore.data_model import master_data_model as D from pycopancore.runners import Runner from pylab import plot, gca, show, figure, subplot, gca, semilogy, legend diff --git a/studies/run_exodus.py b/studies/run_exodus.py index 387a39c..e5ba74b 100755 --- a/studies/run_exodus.py +++ b/studies/run_exodus.py @@ -26,7 +26,7 @@ #import plotly.graph_objs as go from matplotlib.pyplot import plot, gca, show, savefig -import pycopancore.models.exodus as M +from pycopan_more.models import exodus as M from pycopancore.runners.runner import Runner diff --git a/studies/run_exodus_oscillations.py b/studies/run_exodus_oscillations.py index b5defcb..1110484 100755 --- a/studies/run_exodus_oscillations.py +++ b/studies/run_exodus_oscillations.py @@ -26,7 +26,7 @@ import plotly.graph_objs as go from matplotlib.pyplot import plot, gca, show, savefig -import pycopancore.models.exodus as M +from pycopan_more.models import exodus as M from pycopancore.runners.runner import Runner diff --git a/studies/run_exploit.py b/studies/run_exploit.py index 23ab883..b03a7c6 100755 --- a/studies/run_exploit.py +++ b/studies/run_exploit.py @@ -23,7 +23,7 @@ import plotly.offline as py import plotly.graph_objs as go -import pycopancore.models.exploit as M +from pycopan_more.models import exploit as M from pycopancore.runners.runner import Runner #parameters: diff --git a/studies/run_groups_illustration.py b/studies/run_groups_illustration.py index c17fb1d..9b99fdd 100644 --- a/studies/run_groups_illustration.py +++ b/studies/run_groups_illustration.py @@ -22,7 +22,7 @@ import plotly.offline as py import plotly.graph_objs as go -import pycopancore.models.groups_seven_dwarfs as M +from pycopan_more.models import groups_seven_dwarfs as M from pycopancore.runners.runner import Runner # from studies import plot_multilayer as pm diff --git a/studies/run_reg_decisions.py b/studies/run_reg_decisions.py deleted file mode 100755 index 25b1280..0000000 --- a/studies/run_reg_decisions.py +++ /dev/null @@ -1,144 +0,0 @@ -"""Test run script for LPJmL coupling""" - -# This file is part of pycopancore. -# -# Copyright (C) 2022 by COPAN team at Potsdam Institute for Climate -# Impact Research -# -# URL: -import os -# os.chdir("/p/projects/open/Jannes/copan_core/pycopancore") -os.chdir("/p/projects/copan/users/lschwarz/core/pycopancore") - -import pycopancore.models.inseeds_social as M - -# from pycopancore.models import inseeds_social as M - -# standard runner for simulating any model: -from pycopancore.runners.runner import Runner - -from pycopancore import master_data_model as D # to be able to specify variables with physical units - -import numpy as np # which is usually needed -from numpy.random import choice, uniform # to generate random initial conditions - -import pylab as plt # to plot stuff - -# instantiate the model and have it analyse its own structure: -model = M.Model() - -print("te") - -# TODO: initial coupling - -# include config of LPJmL (maybe in own .py) -# from pycoupler.coupler import Coupler -# from pycoupler.data import supply_inputs, preprocess_inputs -# -# -# # paths -# # TODO add other requirements for pycoupler -# model_location = "/home/lschwarz/kopplung" -# base_path = "/p/projects/copan/users/lschwarz/lpjml/data" -# model_path = f"{model_location}/LPJmL_internal" -# config_historic_fn = f"{base_path}/config_historic.json" -# config_coupled_fn = f"{base_path}/config_coupled.json" -# -# # coupled simulation years -start_year = 1981 -end_year = 2005 -# sim_years = range(start_year, end_year+1) -# -# # initiate coupler after run_lpjml on LOGIN NODE 1 -# coupler = Coupler(config_file=config_coupled_fn) -# -# # get and process initial inputs -# inputs = supply_inputs(config_file=config_coupled_fn, -# historic_config_file=config_historic_fn, -# input_path=f"{base_path}/input", -# model_path=model_path, -# start_year=start_year, end_year=start_year) -# input_data = preprocess_inputs(inputs, grid=coupler.grid, time=start_year) - -# input_data["with_tillage"] = input_data["with_tillage"].astype("int32") - -# simulation parameters: - -# coupled simulation years -# years = range(1981, 2006) -# # The following could be your model/program/script -# for year in years: -# # send input data to lpjml -# print(f"year: {year}") -# coupler.send_inputs(input_data, year) -# # read output data -# outputs = coupler.read_outputs(year) -# print(outputs) -# # generate some results based on lpjml outputs -# # .... -# coupler.close_channel() - - -delta_t = 1 # desired temporal resolution of the resulting output. - - -# test_dict_in = {"landuse": np.zeros((1, 64)),"fertilizer_nr": np.zeros((1, 32))} -# test_dict_out = {"cftfrac": np.zeros((1, 32)),"pft_harvestc": np.zeros((1, 32)),"pft_harvestn": np.zeros((1, 32))} - - -# adjust reading and writing as in Jannes' test script -# erst mal benötigt als pre-struktur, kommt dann quasi weg, wenn lpjml output da ist -# fkt die output auf hohem level als argument entgegennimmt -test_dict_in = {"with_tillage": np.zeros((1, 1), dtype=int)} -test_dict_out = {"cftfrac": np.zeros((1, 32)), "pft_harvestc": np.zeros((1, 32))} - -landuse_update_rate = 10 -landuse_update_prob = 1. - - -dt = 1 # desired temporal resolution of the resulting output. - - -# instantiate process taxa: -env = M.Environment( - delta_t=delta_t, # dt should be given to environment probably - start_year=start_year, # our starting point - in_dict=test_dict_in, - out_dict=test_dict_out, - old_out_dict=test_dict_out, - # coupler=coupler - ) -met = M.Metabolism( - landuse_update_rate=landuse_update_rate, - landuse_update_prob=landuse_update_prob - ) -cul = M.Culture( - ) - -# generate entities: - -world = M.World( - environment=env, - metabolism=met, - culture=cul, - ) -soc = M.SocialSystem(world=world) -cell = M.Cell( - social_system=soc, - lpjml_grid_cell_ids=[0], - # landuse = test_dict_in["landuse"][0] - # with_tillage=test_dict_in["with_tillage"][0], - ) -ind = M.Individual(cell=cell) - -# Run the model -# - -runner = Runner(model=model) -traj = runner.run(t_0=start_year, t_1=end_year, dt=dt) - -# TODO: Add some further analysis such as plotting or saving -# plt.plot(traj['t'], traj[M.SocialSystem.population][socs[0]]) -# plt.show() - -# coupler.close_channel() diff --git a/studies/run_reg_decisions_clean copy.py b/studies/run_reg_decisions_clean copy.py deleted file mode 100755 index 821c1b5..0000000 --- a/studies/run_reg_decisions_clean copy.py +++ /dev/null @@ -1,86 +0,0 @@ -"""Test run script for LPJmL coupling""" - -# This file is part of pycopancore. -# -# Copyright (C) 2022 by COPAN team at Potsdam Institute for Climate -# Impact Research -# -# URL: -import os -os.chdir("/p/projects/copan/users/lschwarz/core/pycopancore") - -import pycopancore.models.inseeds_social as M - -# from pycopancore.models import inseeds_social as M - -# standard runner for simulating any model: -from pycopancore.runners.runner import Runner - -from pycopancore import master_data_model as D # to be able to specify variables with physical units - -import numpy as np # which is usually needed -from numpy.random import choice, uniform # to generate random initial conditions - -import pylab as plt # to plot stuff - -# instantiate the model and have it analyse its own structure: -model = M.Model() - - -# # coupled simulation years -start_year = 1981 -end_year = 2005 - - -delta_t = 1 # desired temporal resolution of the resulting output. - -test_dict_in = {"with_tillage": np.zeros((1, 1), dtype=int)} -test_dict_out = {"cftfrac": np.zeros((1, 32)), "pft_harvestc": np.zeros((1, 32))} - -landuse_update_rate = 10 -landuse_update_prob = 1. - - -dt = 1 # desired temporal resolution of the resulting output. - - -# instantiate process taxa: -# env = M.Environment( -# delta_t=delta_t, # dt should be given to environment probably -# start_year=start_year, # our starting point -# in_dict=test_dict_in, -# out_dict=test_dict_out, -# old_out_dict=test_dict_out, -# # coupler=coupler -# ) -# met = M.Metabolism( -# landuse_update_rate=landuse_update_rate,S -# landuse_update_prob=landuse_update_prob -# ) - -# generate entities: -cul = M.Culture( - ) -world = M.World( - culture=cul, - ) -soc = M.SocialSystem(world=world) -cell = M.Cell( - social_system=soc, - # lpjml_grid_cell_ids=[0], - # landuse = test_dict_in["landuse"][0] - # with_tillage=test_dict_in["with_tillage"][0], - ) -ind = M.Individual(cell=cell) - -# Run the model -# - -runner = Runner(model=model) -traj = runner.run(t_0=start_year, t_1=end_year, dt=dt) - -# TODO: Add some further analysis such as plotting or saving -# plt.plot(traj['t'], traj[M.SocialSystem.population][socs[0]]) -# plt.show() - -# coupler.close_channel() diff --git a/studies/run_reg_decisions_clean.py b/studies/run_reg_decisions_clean.py deleted file mode 100755 index a16b63c..0000000 --- a/studies/run_reg_decisions_clean.py +++ /dev/null @@ -1,87 +0,0 @@ -"""Test run script for LPJmL coupling""" - -# This file is part of pycopancore. -# -# Copyright (C) 2022 by COPAN team at Potsdam Institute for Climate -# Impact Research -# -# URL: -import os -# os.chdir("/p/projects/copan/users/lschwarz/core/pycopancore") -os.chdir("/p/projects/open/Jannes/copan_core/pycopancore") - -import pycopancore.models.inseeds_social as M - -# from pycopancore.models import inseeds_social as M - -# standard runner for simulating any model: -from pycopancore.runners.runner import Runner - -from pycopancore.data_model import master_data_model as D # to be able to specify variables with physical units - -import numpy as np # which is usually needed -from numpy.random import choice, uniform # to generate random initial conditions - -import pylab as plt # to plot stuff - -# instantiate the model and have it analyse its own structure: -model = M.Model() - - -# # coupled simulation years -start_year = 1981 -end_year = 2005 - - -delta_t = 1 # desired temporal resolution of the resulting output. - -test_dict_in = {"with_tillage": np.zeros((1, 1), dtype=int)} -test_dict_out = {"cftfrac": np.zeros((1, 32)), "pft_harvestc": np.zeros((1, 32))} - -landuse_update_rate = 10 -landuse_update_prob = 1. - - -dt = 1 # desired temporal resolution of the resulting output. - - -# instantiate process taxa: -# env = M.Environment( -# delta_t=delta_t, # dt should be given to environment probably -# start_year=start_year, # our starting point -# in_dict=test_dict_in, -# out_dict=test_dict_out, -# old_out_dict=test_dict_out, -# # coupler=coupler -# ) -# met = M.Metabolism( -# landuse_update_rate=landuse_update_rate,S -# landuse_update_prob=landuse_update_prob -# ) - -# generate entities: -cul = M.Culture( - ) -world = M.World( - culture=cul, - ) -soc = M.SocialSystem(world=world) -cell = M.Cell( - social_system=soc, - # lpjml_grid_cell_ids=[0], - # landuse = test_dict_in["landuse"][0] - # with_tillage=test_dict_in["with_tillage"][0], - ) -ind = M.Individual(cell=cell) - -# Run the model -# - -runner = Runner(model=model) -traj = runner.run(t_0=start_year, t_1=end_year, dt=dt) - -# TODO: Add some further analysis such as plotting or saving -# plt.plot(traj['t'], traj[M.SocialSystem.population][socs[0]]) -# plt.show() - -# coupler.close_channel() diff --git a/studies/run_seven_dwarfs.py b/studies/run_seven_dwarfs.py index 027d65c..f44aa32 100755 --- a/studies/run_seven_dwarfs.py +++ b/studies/run_seven_dwarfs.py @@ -24,7 +24,7 @@ import plotly.offline as py import plotly.graph_objs as go -import pycopancore.models.seven_dwarfs as M +from pycopan_more.models import seven_dwarfs as M from pycopancore.runners.runner import Runner diff --git a/studies/test_jobsts_prototype_1.py b/studies/test_jobsts_prototype_1.py deleted file mode 100755 index 15a51a3..0000000 --- a/studies/test_jobsts_prototype_1.py +++ /dev/null @@ -1,259 +0,0 @@ -"""Skript to run Jobsts prototype model.""" - -# This file is part of pycopancore. -# -# Copyright (C) 2016-2017 by COPAN team at Potsdam Institute for Climate -# Impact Research -# -# URL: -# Contact: core@pik-potsdam.de -# License: BSD 2-clause license - -from time import time -from numpy import random, array -import numpy as np -import pycopancore.models.jobsts_prototype_1 as M -# import pycopancore.models.only_copan_global_like_carbon_cycle as M -from pycopancore import master_data_model as D -from pycopancore.runners import Runner - -from pylab import plot, gca, show, figure, subplot, gca, semilogy, legend - -# first thing: set seed so that each execution must return same thing: -random.seed(10) # 10 - -# parameters: - -nworlds = 1 # no. worlds -nsocs = 5 # no. social_systems #10 -ncells = 100 # no. cells #100 -ninds = 1000 # no. individuals - -model = M.Model() - -# instantiate process taxa: -environment = M.Environment() -metabolism = M.Metabolism( - renewable_energy_knowledge_spillover_fraction = .1, #.1, #.1, - # 1 w/o protection: success but desertification - # .75 w protection: success (even w/o or w much migration) - # .1 w protection: success but desertification - # 0 w/o protection: very slow success but desertification - # ?: oscillations - basic_emigration_probability_rate = 16e-13, # 5e-13 leads to ca. 5mio. at 10 socs, (real) - ) -culture = M.Culture( - awareness_lower_carbon_density=1e-4, #1e100, # 1e-6? - awareness_upper_carbon_density=2e-4, #1e100, # 2e-6? - awareness_update_rate=0, #1:SUCCESS, #1e-10 - environmental_friendliness_learning_rate=0, #1:SUCCESS - max_protected_terrestrial_carbon_share=0, - ) - -# generate entities and plug them together at random: -worlds = [M.World(environment=environment, metabolism=metabolism, culture=culture, - atmospheric_carbon = 830 * D.gigatonnes_carbon, - upper_ocean_carbon = (5500 - 830 - 2480 - 1125) * D.gigatonnes_carbon - ) for w in range(nworlds)] -social_systems = [M.SocialSystem(world=random.choice(worlds), - has_renewable_subsidy = random.choice([False, True], p=[3/4, 1/4]), #True, #False, - has_emissions_tax = random.choice([False, True], p=[4/5, 1/5]), #True, #False, - has_fossil_ban = False, #True, #False, - time_between_votes = 1e100, #4, #1e100, # 4 - ) for s in range(nsocs)] -cells = [M.Cell(social_system=random.choice(social_systems), - renewable_sector_productivity = 2 * random.rand() - * M.Cell.renewable_sector_productivity.default) - for c in range(ncells)] -individuals = [M.Individual( - cell=random.choice(cells), - is_environmentally_friendly = - random.choice([False, True], p=[.7, .3]), #True, #False, - ) - for i in range(ninds)] - -# initialize block model acquaintance network: -target_degree = 150 -target_degree_samecell = 0.5 * target_degree -target_degree_samesoc = 0.35 * target_degree -target_degree_other = 0.15 * target_degree -p_samecell = target_degree_samecell / (ninds/ncells - 1) -p_samesoc = target_degree_samesoc / (ninds/nsocs - ninds/ncells - 1) -p_other = target_degree_other / (ninds - ninds/nsocs - 1) -for index, i in enumerate(individuals): - for j in individuals[:index]: - if random.uniform() < ( - p_samecell if i.cell == j.cell - else p_samesoc if i.social_system == j.social_system \ - else p_other): - culture.acquaintance_network.add_edge(i, j) -#print("degrees:",culture.acquaintance_network.degree()) - -# distribute area and vegetation randomly but correlatedly: -r = random.uniform(size=ncells) -Sigma0 = 1.5e8 * D.square_kilometers * r / sum(r) -M.Cell.land_area.set_values(cells, Sigma0) -# print(M.Cell.land_area.get_values(cells)) - -r += random.uniform(size=ncells) -L0 = 2480 * D.gigatonnes_carbon * r / sum(r) # 2480 is yr 2000 -M.Cell.terrestrial_carbon.set_values(cells, L0) -# print(M.Cell.terrestrial_carbon.get_values(cells)) - -r = np.exp(random.normal(size=ncells)) -G0 = 1125 * D.gigatonnes_carbon * r / sum(r) # 1125 is yr 2000 -M.Cell.fossil_carbon.set_values(cells, G0) -# print(M.Cell.fossil_carbon.get_values(cells)) - -r = random.uniform(size=nsocs) -P0 = 6e9 * D.people * r / sum(r) # 500e9 is middle ages, 6e9 would be yr 2000 -M.SocialSystem.population.set_values(social_systems, P0) -M.SocialSystem.migrant_population.set_values(social_systems, P0 * 250e6/6e9) -for s in social_systems: - s.max_protected_terrestrial_carbon = 0.90 * sum(c.terrestrial_carbon for c in s.cells) - -# print(M.SocialSystem.population.get_values(social_systems)) - -r = random.uniform(size=nsocs) -K0 = sum(P0) * 1e4 * D.dollars/D.people * r / sum(r) # ? -M.SocialSystem.physical_capital.set_values(social_systems, K0) -# print(M.SocialSystem.physical_capital.get_values(social_systems)) - -# for renewables, do NOT divide by number of socs: -r = random.uniform(size=nsocs) -# in AWS paper: 1e12 (alternatively: 1e13): -S0 = 1e12 * D.gigajoules * r / r.mean() -M.SocialSystem.renewable_energy_knowledge.set_values(social_systems, S0) -# print(M.SocialSystem.renewable_energy_knowledge.get_values(social_systems)) - -# TODO: add noise to parameters - -w = worlds[0] -s = social_systems[0] -c = cells[0] -for v in environment.variables: print(v,v.get_value(environment)) -for v in metabolism.variables: print(v,v.get_value(metabolism)) -for v in w.variables: print(v,v.get_value(w)) -for v in s.variables: print(v,v.get_value(s)) -for v in c.variables: print(v,v.get_value(c)) - -# from pycopancore.private._expressions import eval -# import pycopancore.model_components.base.interface as B -# import sympy as sp - -runner = Runner(model=model) - -start = time() -traj = runner.run(t_0=2000, t_1=2000+100, dt=1, add_to_output=[M.Individual.represented_population]) - - -for v in environment.variables: print(v,v.get_value(environment)) -for v in metabolism.variables: print(v,v.get_value(metabolism)) -for v in w.variables: print(v,v.get_value(w)) -for v in s.variables: print(v,v.get_value(s)) -for v in c.variables: print(v,v.get_value(c)) - - -from pickle import dump -tosave = { - v.owning_class.__name__ + "." - + v.codename: {str(e): traj[v][e] - for e in traj[v].keys() - } - for v in traj.keys() if v is not "t" - } -tosave["t"] = traj["t"] -dump(tosave, open("/home/jobst/work/without.pickle","wb")) -print(time()-start, " seconds") - -t = np.array(traj['t']) -print("max. time step", (t[1:]-t[:-1]).max()) - -figure() -lws = 1 - -subplot(511) # cultural -for i, s in enumerate(social_systems): -# plot(t[3:], traj[M.SocialSystem.protected_terrestrial_carbon_share][s][3:],color="green",lw=lws, label=None if i else "share of protected biomass") - plot(t[3:], traj[M.SocialSystem.has_renewable_subsidy][s][3:]*1,color="darkorange",lw=lws, label=None if i else "renewable subsidy in place?") - plot(t[3:], traj[M.SocialSystem.has_emissions_tax][s][3:]*1,color="blue",lw=lws, label=None if i else "emissions tax in place?") - plot(t[3:], traj[M.SocialSystem.has_fossil_ban][s][3:]*1,color="gray",lw=lws, label=None if i else "fossil ban in place?") -legend() - -subplot(512) # metabolic, logscale: capital, knowledge, production, wellbeing -for i, s in enumerate(social_systems): - semilogy(t[3:], array(traj[M.SocialSystem.physical_capital][s][3:])/1e6, color="black", lw=lws, label=None if i else "physical capital [mio. $]") - semilogy(t[3:], array(traj[M.SocialSystem.renewable_energy_knowledge][s][3:])/1e6, color="darkorange", lw=lws, label=None if i else "renewable energy knowledge [PJ]") - semilogy(t[3:], array(traj[M.SocialSystem.economic_output_flow][s][3:])/1e6, color="blue", lw=lws, label=None if i else "GDP [mio. $ per year]") - semilogy(t[3:], array(traj[M.SocialSystem.wellbeing][s][3:]), color="magenta",lw=lws, label=None if i else "wellbeing [$ per year and person]") -legend() - -subplot(513) # metabolic: population (left), migration (right) -ax1 = gca() -#ax1.set_xlabel('years') -# Make the y-axis label, ticks and tick labels match the line color. -ax1.set_ylabel('humans') -ax1.tick_params('y') -ax2 = ax1.twinx() -ax2.set_ylabel('humans per year', color='gray') -ax2.tick_params('y', colors='gray') -for i, s in enumerate(social_systems): - ax1.plot(t[3:], traj[M.SocialSystem.population][s][3:],color="black",lw=lws, label=None if i else "population") - ax1.plot(t[3:], traj[M.SocialSystem.migrant_population][s][3:],"-.",color="black",lw=lws, label=None if i else "migrant population") - ax2.plot(t[3:], traj[M.SocialSystem.immigration][s][3:],"--",color="gray",lw=lws, label=None if i else "immigration flow") - ax2.plot(t[3:], traj[M.SocialSystem.emigration][s][3:],":",color="gray",lw=lws, label=None if i else "emigration flow") -ax1.legend(loc=2) -ax2.legend(loc=1) - -subplot(514) # metabolic: energy mix -for i, s in enumerate(social_systems): - Es = array(traj[M.SocialSystem.secondary_energy_flow][s][3:]) - plot(t[3:], array(traj[M.SocialSystem.biomass_input_flow][s][3:]) * metabolism.biomass_energy_density / Es, color="green", lw=lws, label=None if i else "share of biomass") - plot(t[3:], array(traj[M.SocialSystem.fossil_fuel_input_flow][s][3:]) * metabolism.fossil_energy_density / Es, color="gray", lw=lws, label=None if i else "share of fossils") - plot(t[3:], array(traj[M.SocialSystem.renewable_energy_input_flow][s][3:]) / Es, color="darkorange", lw=lws, label=None if i else "share of renewables") -legend() - -subplot(515) # natural -plot(t[3:], traj[M.World.atmospheric_carbon][worlds[0]][3:], color="cyan", lw=3, label="atmospheric carbon") -plot(t[3:], traj[M.World.upper_ocean_carbon][worlds[0]][3:], color="blue", lw=3, label="upper ocean carbon") -plot(t[3:], traj[M.World.terrestrial_carbon][worlds[0]][3:], color="green", lw=3, label="terrestrial carbon") -plot(t[3:], traj[M.World.fossil_carbon][worlds[0]][3:], color="gray", lw=3, label="fossil carbon") -for i, s in enumerate(social_systems): - plot(t[3:], traj[M.SocialSystem.protected_terrestrial_carbon][s][3:],color="green",lw=lws, label=None if i else "protected biomass") -gca().set_ylabel('gigatonnes carbon') -legend() - -print("\nyr 2000 values (real):") -print("emigration (5e6):",sum(traj[M.SocialSystem.emigration][s][5] for s in social_systems)) # should be ca. 5e6 -print("photo (123):",sum(traj[M.Cell.photosynthesis_carbon_flow][c][5] for c in cells)) -print("resp (118):",sum(traj[M.Cell.terrestrial_respiration_carbon_flow][c][5] for c in cells)) -print("GWP (4e13):",sum(traj[M.SocialSystem.economic_output_flow][s][5] for s in social_systems)) # should be ca. 4e13 -Bglobal = sum(traj[M.SocialSystem.biomass_input_flow][s][5] for s in social_systems) * D.gigatonnes_carbon / D.years -Fglobal = sum(traj[M.SocialSystem.fossil_fuel_input_flow][s][5] for s in social_systems) * D.gigatonnes_carbon / D.years -Rglobal = sum(traj[M.SocialSystem.renewable_energy_input_flow][s][5] for s in social_systems) * D.gigajoules / D.years -print("B (3), F (11), R(100):", - Bglobal.tostr(unit=D.gigatonnes_carbon/D.years), # should be ca. 3 - Fglobal.tostr(unit=D.gigatonnes_carbon/D.years), # should be ca. 11 - Rglobal.tostr(unit=D.gigawatts)) # last should be ca. 100 -#print((Bglobal * metabolism.biomass_energy_density * D.gigajoules/D.gigatonnes_carbon).tostr(unit=D.gigawatts), -# (Fglobal * metabolism.fossil_energy_density * D.gigajoules/D.gigatonnes_carbon).tostr(unit=D.gigawatts), -# Rglobal.tostr(unit=D.gigawatts), "(100)") # last should be ca. 100 -print("life exp. at end:",1/np.mean([traj[M.SocialSystem.mortality][s][-1] for s in social_systems])) -print("cap. deprec. at begin (0.1?):",np.mean([traj[M.SocialSystem.physical_capital_depreciation_rate][s][5] for s in social_systems])) -print("cap. deprec. at end (0.1?):",np.mean([traj[M.SocialSystem.physical_capital_depreciation_rate][s][-1] for s in social_systems])) -print("deaths at begin (>250000?):",sum(traj[M.SocialSystem.deaths][s][5] for s in social_systems)) -print("deaths at end (>250000?):",sum(traj[M.SocialSystem.deaths][s][-1] for s in social_systems)) -print("temp. at begin:",traj[M.World.surface_air_temperature][worlds[0]][5]) -print("temp. at end:",traj[M.World.surface_air_temperature][worlds[0]][-1]) -print("prot. carbon share:",[traj[M.SocialSystem.protected_terrestrial_carbon][s][-1]/sum(traj[M.Cell.terrestrial_carbon][c][-1]for c in s.cells) for s in social_systems]) -print(traj[M.World.terrestrial_carbon][worlds[0]][-1],sum(traj[M.Cell.terrestrial_carbon][c][-1] for c in worlds[0].cells)) - -show() - -# TODO: -# policy shares, env. friendly shares -# transparancy, means -# wellb. abs., renew., pop. log -# total protected -# horiz. -# save dump with codename,uid as key \ No newline at end of file diff --git a/studies/test_our_model.py b/studies/test_our_model.py index 91d46a3..fa8abd3 100755 --- a/studies/test_our_model.py +++ b/studies/test_our_model.py @@ -12,9 +12,9 @@ from time import time from numpy import random import numpy as np -import pycopancore.models.our_model as M +from pycopan_more.models import our_model as M # import pycopancore.models.only_copan_global_like_carbon_cycle as M -from pycopancore import master_data_model as D +from pycopancore.data_model import master_data_model as D from pycopancore.runners import Runner # import plotly.plotly as py diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..a9d6220 --- /dev/null +++ b/uv.lock @@ -0,0 +1,681 @@ +version = 1 +revision = 3 +requires-python = ">=3.14" + +[[package]] +name = "astroid" +version = "4.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/07/63/0adf26577da5eff6eb7a177876c1cfa213856be9926a000f65c4add9692b/astroid-4.0.4.tar.gz", hash = "sha256:986fed8bcf79fb82c78b18a53352a0b287a73817d6dbcfba3162da36667c49a0", size = 406358, upload-time = "2026-02-07T23:35:07.509Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/cf/1c5f42b110e57bc5502eb80dbc3b03d256926062519224835ef08134f1f9/astroid-4.0.4-py3-none-any.whl", hash = "sha256:52f39653876c7dec3e3afd4c2696920e05c83832b9737afc21928f2d2eb7a753", size = 276445, upload-time = "2026-02-07T23:35:05.344Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "contourpy" +version = "1.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/8b/4546f3ab60f78c514ffb7d01a0bd743f90de36f0019d1be84d0a708a580a/contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a", size = 292189, upload-time = "2025-07-26T12:02:16.095Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e1/3542a9cb596cadd76fcef413f19c79216e002623158befe6daa03dbfa88c/contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77", size = 273251, upload-time = "2025-07-26T12:02:17.524Z" }, + { url = "https://files.pythonhosted.org/packages/b1/71/f93e1e9471d189f79d0ce2497007731c1e6bf9ef6d1d61b911430c3db4e5/contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5", size = 335810, upload-time = "2025-07-26T12:02:18.9Z" }, + { url = "https://files.pythonhosted.org/packages/91/f9/e35f4c1c93f9275d4e38681a80506b5510e9327350c51f8d4a5a724d178c/contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4", size = 382871, upload-time = "2025-07-26T12:02:20.418Z" }, + { url = "https://files.pythonhosted.org/packages/b5/71/47b512f936f66a0a900d81c396a7e60d73419868fba959c61efed7a8ab46/contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36", size = 386264, upload-time = "2025-07-26T12:02:21.916Z" }, + { url = "https://files.pythonhosted.org/packages/04/5f/9ff93450ba96b09c7c2b3f81c94de31c89f92292f1380261bd7195bea4ea/contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3", size = 363819, upload-time = "2025-07-26T12:02:23.759Z" }, + { url = "https://files.pythonhosted.org/packages/3e/a6/0b185d4cc480ee494945cde102cb0149ae830b5fa17bf855b95f2e70ad13/contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b", size = 1333650, upload-time = "2025-07-26T12:02:26.181Z" }, + { url = "https://files.pythonhosted.org/packages/43/d7/afdc95580ca56f30fbcd3060250f66cedbde69b4547028863abd8aa3b47e/contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36", size = 1404833, upload-time = "2025-07-26T12:02:28.782Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e2/366af18a6d386f41132a48f033cbd2102e9b0cf6345d35ff0826cd984566/contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d", size = 189692, upload-time = "2025-07-26T12:02:30.128Z" }, + { url = "https://files.pythonhosted.org/packages/7d/c2/57f54b03d0f22d4044b8afb9ca0e184f8b1afd57b4f735c2fa70883dc601/contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd", size = 232424, upload-time = "2025-07-26T12:02:31.395Z" }, + { url = "https://files.pythonhosted.org/packages/18/79/a9416650df9b525737ab521aa181ccc42d56016d2123ddcb7b58e926a42c/contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339", size = 198300, upload-time = "2025-07-26T12:02:32.956Z" }, + { url = "https://files.pythonhosted.org/packages/1f/42/38c159a7d0f2b7b9c04c64ab317042bb6952b713ba875c1681529a2932fe/contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772", size = 306769, upload-time = "2025-07-26T12:02:34.2Z" }, + { url = "https://files.pythonhosted.org/packages/c3/6c/26a8205f24bca10974e77460de68d3d7c63e282e23782f1239f226fcae6f/contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77", size = 287892, upload-time = "2025-07-26T12:02:35.807Z" }, + { url = "https://files.pythonhosted.org/packages/66/06/8a475c8ab718ebfd7925661747dbb3c3ee9c82ac834ccb3570be49d129f4/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13", size = 326748, upload-time = "2025-07-26T12:02:37.193Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a3/c5ca9f010a44c223f098fccd8b158bb1cb287378a31ac141f04730dc49be/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe", size = 375554, upload-time = "2025-07-26T12:02:38.894Z" }, + { url = "https://files.pythonhosted.org/packages/80/5b/68bd33ae63fac658a4145088c1e894405e07584a316738710b636c6d0333/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f", size = 388118, upload-time = "2025-07-26T12:02:40.642Z" }, + { url = "https://files.pythonhosted.org/packages/40/52/4c285a6435940ae25d7410a6c36bda5145839bc3f0beb20c707cda18b9d2/contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0", size = 352555, upload-time = "2025-07-26T12:02:42.25Z" }, + { url = "https://files.pythonhosted.org/packages/24/ee/3e81e1dd174f5c7fefe50e85d0892de05ca4e26ef1c9a59c2a57e43b865a/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4", size = 1322295, upload-time = "2025-07-26T12:02:44.668Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b2/6d913d4d04e14379de429057cd169e5e00f6c2af3bb13e1710bcbdb5da12/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f", size = 1391027, upload-time = "2025-07-26T12:02:47.09Z" }, + { url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428, upload-time = "2025-07-26T12:02:48.691Z" }, + { url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331, upload-time = "2025-07-26T12:02:50.137Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" }, +] + +[[package]] +name = "coverage" +version = "7.14.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b4/91/0a7c28934e50d8ac9a7b117712d176f2953c3170bccced5eaacfa3e96175/coverage-7.14.3.tar.gz", hash = "sha256:1a7563a443f3d53fdeb040ec8c9f7466aed7ca3dc5891aa09d3ca3625fa4387f", size = 924398, upload-time = "2026-06-22T23:10:25.584Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/56/14e3b97facbfa1304dd19e676e26599ad359f04714bed32f7f1c5a88efdc/coverage-7.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:605ab2b566a22bd94834529d66d295c364aba84afd3e5498285c7a524017b1fc", size = 220741, upload-time = "2026-06-22T23:09:21.616Z" }, + { url = "https://files.pythonhosted.org/packages/12/1d/db378b5cca433b90b893f26dab728b280ddd89f272a1fdfed4aeaa05c686/coverage-7.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a3c2134809e80fac091bfed18a6991b5a5eb5df5ae32b17ac4f4f99864b73dd7", size = 221068, upload-time = "2026-06-22T23:09:23.452Z" }, + { url = "https://files.pythonhosted.org/packages/47/f0/3f8421b20d9c4fcd39be9a8ca3c3fda8bc204b44efbd09fede153afd3e2f/coverage-7.14.3-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c02efd507227bde9969cab0db8f48890eb3b5dcad6afac57a4792df4133543ce", size = 252117, upload-time = "2026-06-22T23:09:25.458Z" }, + { url = "https://files.pythonhosted.org/packages/27/ca/59ea35fb99743549ec8b37eff141ece4431fea590c89e536ed8032ef45cf/coverage-7.14.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1bb93c2aa61d2a5b38f1526546d95cf4132cb681e541a337bf8dfd092be816e5", size = 254622, upload-time = "2026-06-22T23:09:27.523Z" }, + { url = "https://files.pythonhosted.org/packages/c8/25/ec6de51ae7493b92a1cf74d1b763121c29636759167e2a593ba4db5881e4/coverage-7.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f502e948e03e866538048bba081c075caaa62e5bda6ea5b7432e45f587eb462a", size = 255968, upload-time = "2026-06-22T23:09:29.43Z" }, + { url = "https://files.pythonhosted.org/packages/5d/05/c8bfc77823f42b4664fb25842f13b567022f6f84a4c83c8ecbb16734b7cb/coverage-7.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9973ef2463f8e6cfb61a6324126bb3e17d67a85f22f58d856e583ea2e3ca6501", size = 258284, upload-time = "2026-06-22T23:09:31.397Z" }, + { url = "https://files.pythonhosted.org/packages/f6/15/1d1b242027124a32b26ef01f82018b8c4ef34ef174aa6aeba7b1eeef48e8/coverage-7.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9be4e7d4c5ca0427889f8f9d614bd630c2be741b1de7699bca3b2b6c0e41003e", size = 252143, upload-time = "2026-06-22T23:09:33.256Z" }, + { url = "https://files.pythonhosted.org/packages/74/b6/d2a9842fd2a5d7d27f1ac851c043a734a494ad75402c5331db3da79ed691/coverage-7.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a574912f3bde4b0619f6e97d01aa590b70998859244793769eb3a6df78ee56d3", size = 253976, upload-time = "2026-06-22T23:09:35.351Z" }, + { url = "https://files.pythonhosted.org/packages/fd/30/e1600ddf7e226db5558bb5323d2186fff00f505c4b764643ec89ce5d8175/coverage-7.14.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:e343fb086c9cd780b38622fea7c369acd64c1a0724312149b5d769c387a2b1f5", size = 251942, upload-time = "2026-06-22T23:09:37.313Z" }, + { url = "https://files.pythonhosted.org/packages/d9/2c/9159de64f9dd648e324328d588a44cfab1e331eb5259ce1141afe2a92dfb/coverage-7.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:3c68df8e61f1e09633fefc7538297145623957a048534368c9d212782aa5e845", size = 256220, upload-time = "2026-06-22T23:09:39.165Z" }, + { url = "https://files.pythonhosted.org/packages/91/67/b7f536cc2c124f48e91b22fbb741d2261f4e3d310faf6f76007f47566e5d/coverage-7.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3e5b550a128419373c2f6cec28a244207013ef15f5cbcff6a5ca09d1dfaaf027", size = 251756, upload-time = "2026-06-22T23:09:41.056Z" }, + { url = "https://files.pythonhosted.org/packages/dd/ec/f3718038e2d4860c715a55428377ca7f6c75872caf98cabd982e1d76967d/coverage-7.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2bfc4dd0a912329eccc7484a7d0b2a38032b38c40663b1e1ac595f10c457954b", size = 253413, upload-time = "2026-06-22T23:09:43.306Z" }, + { url = "https://files.pythonhosted.org/packages/b8/a5/91f11efeef89b3cc9b30461128db15b0511ef813ab889a7b7ab636b3a497/coverage-7.14.3-cp314-cp314-win32.whl", hash = "sha256:0423d64c013057a06e70f070f073cec4b0cbc7d2b27f3c7007292f2ff1d52965", size = 222946, upload-time = "2026-06-22T23:09:45.261Z" }, + { url = "https://files.pythonhosted.org/packages/58/fd/98ac9f524d9ec378de831c034dbdeb544ca7ef7d2d9c9996daf232a037fd/coverage-7.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:92c22e19ce64ca3f2ad751f16f14df1468b4c231bd6af97185063a9c292a0cb3", size = 223436, upload-time = "2026-06-22T23:09:47.177Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a0/7cd612d650a772a0ae80144443406bf61981c896c3d57c9e6e79fb2cdbd1/coverage-7.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:41de778bd41780586e2b04912079c73089ab5d839624e28db3bdb26de638da92", size = 222861, upload-time = "2026-06-22T23:09:49.384Z" }, + { url = "https://files.pythonhosted.org/packages/55/57/017353fab573779c0d00448e47d102edd36c792f7b6f233a4d89a7a08384/coverage-7.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:8427f370ca67db4c975d2a26acfc0e5783ca0b52444dbc50278ace0f35445949", size = 221474, upload-time = "2026-06-22T23:09:51.417Z" }, + { url = "https://files.pythonhosted.org/packages/69/92/90cf1f1a5c468a9c1b7ba2716e0e205293ad9b02f5f573a6de4318b15ba1/coverage-7.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d8e88f335544a47e22ae2e45b344772925ec65166555c958720d5ed971880891", size = 221738, upload-time = "2026-06-22T23:09:53.487Z" }, + { url = "https://files.pythonhosted.org/packages/a4/c0/4df964fa539f8399fd7679c09c472d73744de334686fd3f01e3a2465ce4e/coverage-7.14.3-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:beaab199b9e5ceaf5a225e16a9d4df136f2a1eae0a5c20de1e277c8a5225f388", size = 263101, upload-time = "2026-06-22T23:09:55.895Z" }, + { url = "https://files.pythonhosted.org/packages/06/76/e5d33b2576ae3bf2be2058cd1cae57774b61e400f2c3c58f3783dc2ffb4a/coverage-7.14.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3ff255799f5a1676c71c1c32ec01fd043aa09d57b3d95764b24992757184784", size = 265225, upload-time = "2026-06-22T23:09:57.904Z" }, + { url = "https://files.pythonhosted.org/packages/61/d2/e52419afe391a39ba27fdefaf0737d8e34bf03faef6ab3b3006545bbd0d0/coverage-7.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:878832eaac515b62decfa76965aed558775f86bf1fc8cca76993c0c84ae31aed", size = 267643, upload-time = "2026-06-22T23:09:59.938Z" }, + { url = "https://files.pythonhosted.org/packages/58/7a/f2625d8d5006b6b20fba5afaef00b24a763fe96476ea798a3076cbc1f84e/coverage-7.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:611e62cb9386096d81b63e0a05330750268617231e7bd598e1fe77482a2c58a5", size = 268762, upload-time = "2026-06-22T23:10:01.943Z" }, + { url = "https://files.pythonhosted.org/packages/7d/bf/908024006bba57127354d74e938954b9c3cd765cc2e0412dc9c37b415cda/coverage-7.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:02c41de2a88011b893050fc9830267d927a50a215f7ad5ec17349db7090ccf26", size = 262208, upload-time = "2026-06-22T23:10:03.954Z" }, + { url = "https://files.pythonhosted.org/packages/34/a0/d4f9296441b909817442fdb26bd77a698f08272ec683a7394b00eb2e47a0/coverage-7.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:526ce9721116af23b1065089f0b75046fe521e7772ab94b641cd66b7a0421889", size = 265096, upload-time = "2026-06-22T23:10:05.936Z" }, + { url = "https://files.pythonhosted.org/packages/e8/da/4ae4f3f4e477b56a4ce1e5c48a35eff38a94b50130ce5bdc897024741cfc/coverage-7.14.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e4ed44705ca4bead6fc977a8b741f2145608289b33c8a9b42a95d0f15aedbf4d", size = 262699, upload-time = "2026-06-22T23:10:07.973Z" }, + { url = "https://files.pythonhosted.org/packages/d8/7a/6927148073ff32856d78baa77b4ddc07a9be7e90020f9db0661c4ca523a1/coverage-7.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:2415902f385a23dcc4ccd26e0ba803249a169af6a930c003a4c715eeb9a5444e", size = 266433, upload-time = "2026-06-22T23:10:10.145Z" }, + { url = "https://files.pythonhosted.org/packages/f7/a7/774f658dbe9c4c3f5daa86a87e0459ac3832e4e3cc67affe078547f727b9/coverage-7.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:b75ee850fc2d7c831e883220c445b035f2224de2ba6103f1e56dbd237ab913f7", size = 261547, upload-time = "2026-06-22T23:10:12.191Z" }, + { url = "https://files.pythonhosted.org/packages/3d/14/a0c18c0376c43cbf973f43ef6ca20019c950597180e6396232f7b6a27102/coverage-7.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dc9b4e35e7c3920e925ba7f14886fd5fbe481232754624e832ddba66c7535635", size = 263859, upload-time = "2026-06-22T23:10:14.492Z" }, + { url = "https://files.pythonhosted.org/packages/10/ac/43a3d0f460af524b131a6191805bc5d18b806ab4e828fbf82e8c8c3af446/coverage-7.14.3-cp314-cp314t-win32.whl", hash = "sha256:7b27c822a8161afbe48e99f1adfb098d270ae7e0f7d7b0555ce110529bdb69cc", size = 223250, upload-time = "2026-06-22T23:10:16.758Z" }, + { url = "https://files.pythonhosted.org/packages/3f/5f/d5e5c56b0712e96ce8f69fe7dbf229ff938b437bc50862743c8a0d2cea84/coverage-7.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:39e1dbbb6ff2c338e0196a482558a792a1de3aa64261196f5cdb3da016ad9cda", size = 224082, upload-time = "2026-06-22T23:10:19.23Z" }, + { url = "https://files.pythonhosted.org/packages/62/35/947cbd5be1d3bcbbdc43d6791de8a56c6501903311d42915ae06a82815f0/coverage-7.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:68520c90babfa2d560eca6d497921ed3a4f469623bd709733124491b2aa8ef3f", size = 223400, upload-time = "2026-06-22T23:10:21.24Z" }, + { url = "https://files.pythonhosted.org/packages/eb/e3/a0aa32bfa3a081951f60a23bc0e7b512891ef0eecda1153cf1d8ba36c6b1/coverage-7.14.3-py3-none-any.whl", hash = "sha256:fb7e18afb6e903c1a92401a2f0501ac277dca527bb9ca6fe1f691a8a0026a0e8", size = 212469, upload-time = "2026-06-22T23:10:23.405Z" }, +] + +[[package]] +name = "cycler" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, +] + +[[package]] +name = "dill" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/81/e1/56027a71e31b02ddc53c7d65b01e68edf64dea2932122fe7746a516f75d5/dill-0.4.1.tar.gz", hash = "sha256:423092df4182177d4d8ba8290c8a5b640c66ab35ec7da59ccfa00f6fa3eea5fa", size = 187315, upload-time = "2026-01-19T02:36:56.85Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl", hash = "sha256:1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d", size = 120019, upload-time = "2026-01-19T02:36:55.663Z" }, +] + +[[package]] +name = "fonttools" +version = "4.63.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/69/c97f2c18e0db87d2c7b15da1974dace76ae938f1cfa22e2727a648b7ed43/fonttools-4.63.0.tar.gz", hash = "sha256:caeb583deeb5168e694b65cda8b4ee62abedfa66cf88488734466f2366b9c4e0", size = 3597189, upload-time = "2026-05-14T12:04:30.958Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/d2/23d25e3f247b328be58d04a4c9f894178a0d1eda7d42867cfb388adaf416/fonttools-4.63.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fd1e3094f42d806d3d7c79162fc59e5910fcbe3a7360c385b8da969bc4493745", size = 2875338, upload-time = "2026-05-14T12:03:50.052Z" }, + { url = "https://files.pythonhosted.org/packages/cd/58/7dfa0c761cb3b2964e2a84c4dc986c926a87de0cb9fb60d5b28ded3f2914/fonttools-4.63.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:6e528da43bc3791085f8cb6141b1d13e459226790240340fcbb4625649238b03", size = 2422661, upload-time = "2026-05-14T12:03:52.154Z" }, + { url = "https://files.pythonhosted.org/packages/dd/87/64cfa18a7a1621d17b7f4502b2b0ed8a135a90c3db51ea590ee99043e76b/fonttools-4.63.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b2248c5decb223562f7902ff6325077a073f608ee8e33e88ad88db734eb9f49", size = 5010526, upload-time = "2026-05-14T12:03:54.647Z" }, + { url = "https://files.pythonhosted.org/packages/36/e1/a8933a72c45a87177fbde2696e0d0755c8c9062f8c077a961c6215fa27b1/fonttools-4.63.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:308f957cdeaf8abe4e5f2f124902ef405448af92c90f80e302a3b771c2e6116b", size = 4923946, upload-time = "2026-05-14T12:03:56.984Z" }, + { url = "https://files.pythonhosted.org/packages/27/60/872e6e233b8c5e8b41413796ff18b7fe479661bd40147e071b450dfad7a1/fonttools-4.63.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bf00f21eb5fb721dbaf73d1e9da6d02a1af7768f2ebcf9798be98beab8ba90f6", size = 4962489, upload-time = "2026-05-14T12:03:59.443Z" }, + { url = "https://files.pythonhosted.org/packages/30/c4/83c24f2ec38b90cfda84bf4b1a1f49df80e84a1db4e7ac6e0d41bf23bc39/fonttools-4.63.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c1aaa4b9c75798400ac043ce04d74e7830376c85095a5a6ed7cba2f17a266bf4", size = 5071870, upload-time = "2026-05-14T12:04:02.122Z" }, + { url = "https://files.pythonhosted.org/packages/de/40/3ae22b60ff1d41ce0bd044b31238cdc72cef99f28b976f1e128ebd618c9b/fonttools-4.63.0-cp314-cp314-win32.whl", hash = "sha256:22693918177bd9ceabec4736d338045f357769416fc6b0b2508eefef75b08616", size = 2295026, upload-time = "2026-05-14T12:04:04.47Z" }, + { url = "https://files.pythonhosted.org/packages/c3/d4/98078064ccc76b45cb0f6c002452011e93c4bd26f6850344f0951cc1fe89/fonttools-4.63.0-cp314-cp314-win_amd64.whl", hash = "sha256:7d782fac32985914c351556f68ac0855391572bcd87de50e05970d3cd4c96fc5", size = 2347454, upload-time = "2026-05-14T12:04:06.752Z" }, + { url = "https://files.pythonhosted.org/packages/49/4e/652d1580c5f4e39f7d103b0c793e4773129ad633dce4addd0cf4dfebde02/fonttools-4.63.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:6db5140a60a5d731d21ec076745b40a310607731b0a565b50776393188649001", size = 2958152, upload-time = "2026-05-14T12:04:08.706Z" }, + { url = "https://files.pythonhosted.org/packages/0e/55/ad864c9a9b219f552eb46b32cd7906c466e5a578ba0c3abfcc0fe7413eb6/fonttools-4.63.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7d76edbff9014094dbf03bd2d074709dfa6ec7aba13d838c937a2b33d2d6a86e", size = 2460809, upload-time = "2026-05-14T12:04:10.783Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2b/0aa8db70f18cf52e49b4ed5ecec68547f981160bf5ded3b5aed6faa0a6f9/fonttools-4.63.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0eac00b9118c3c2f87d272e45341871c5b3066baa3c86897fa634a7c3fb59096", size = 5148649, upload-time = "2026-05-14T12:04:12.747Z" }, + { url = "https://files.pythonhosted.org/packages/7f/63/18e4369c25043096f1048e0c9915951adc4f842bd81c6b18155824d6fa99/fonttools-4.63.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:51394295f1a51de8b5f30bdb1e1b9a4231536c7064ef5c6e211eec19fa36036f", size = 4932147, upload-time = "2026-05-14T12:04:14.806Z" }, + { url = "https://files.pythonhosted.org/packages/a1/3f/67f3eac2ffd8a98446c5022f8ed3864eac878a5ff7af8df4c8286dba16cc/fonttools-4.63.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9e12f105d2b6342c559c298afb674006bb2893afc7102dcf8a1b55b0486b4e40", size = 5027237, upload-time = "2026-05-14T12:04:17.675Z" }, + { url = "https://files.pythonhosted.org/packages/1a/ba/4e6214cb38a7b04779e97bb7636de9a5c7f20af7018d03dee0b64c08510a/fonttools-4.63.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:796f27556dbe094c4824f75ca85267e4df776c79036c8441469a4df37038c196", size = 5053933, upload-time = "2026-05-14T12:04:20.818Z" }, + { url = "https://files.pythonhosted.org/packages/34/3b/214dcc19ee31d3d38fb5ad2755c11ef0514e5dc300bbaf41c0b69f393799/fonttools-4.63.0-cp314-cp314t-win32.whl", hash = "sha256:948428a275741f0b64b113c955425a953314f4b9ab9997f73a72c83e68e569c8", size = 2359326, upload-time = "2026-05-14T12:04:24.22Z" }, + { url = "https://files.pythonhosted.org/packages/dd/1e/3ff1a9b523058c2eeb6a9d50f5574e2a738200d0d94107d5bc4105e8da3f/fonttools-4.63.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6d4741eb179121cab9eea4cb2393d24492373a260d7945006358c08cfbf45419", size = 2425829, upload-time = "2026-05-14T12:04:26.829Z" }, + { url = "https://files.pythonhosted.org/packages/2c/47/c99d5268f354002ce80f8d029cd9d7d872969da1de8b93d32de4dc56d6f4/fonttools-4.63.0-py3-none-any.whl", hash = "sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d", size = 1164562, upload-time = "2026-05-14T12:04:29.092Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "isort" +version = "8.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ef/7c/ec4ab396d31b3b395e2e999c8f46dec78c5e29209fac49d1f4dace04041d/isort-8.0.1.tar.gz", hash = "sha256:171ac4ff559cdc060bcfff550bc8404a486fee0caab245679c2abe7cb253c78d", size = 769592, upload-time = "2026-02-28T10:08:20.685Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3e/95/c7c34aa53c16353c56d0b802fba48d5f5caa2cdee7958acbcb795c830416/isort-8.0.1-py3-none-any.whl", hash = "sha256:28b89bc70f751b559aeca209e6120393d43fbe2490de0559662be7a9787e3d75", size = 89733, upload-time = "2026-02-28T10:08:19.466Z" }, +] + +[[package]] +name = "kiwisolver" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/67/9c61eccb13f0bdca9307614e782fec49ffdde0f7a2314935d489fa93cd9c/kiwisolver-1.5.0.tar.gz", hash = "sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a", size = 103482, upload-time = "2026-03-09T13:15:53.382Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/d7/060f45052f2a01ad5762c8fdecd6d7a752b43400dc29ff75cd47225a40fd/kiwisolver-1.5.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8df31fe574b8b3993cc61764f40941111b25c2d9fea13d3ce24a49907cd2d615", size = 123231, upload-time = "2026-03-09T13:14:41.323Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a7/78da680eadd06ff35edef6ef68a1ad273bad3e2a0936c9a885103230aece/kiwisolver-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1d49a49ac4cbfb7c1375301cd1ec90169dfeae55ff84710d782260ce77a75a02", size = 66489, upload-time = "2026-03-09T13:14:42.534Z" }, + { url = "https://files.pythonhosted.org/packages/49/b2/97980f3ad4fae37dd7fe31626e2bf75fbf8bdf5d303950ec1fab39a12da8/kiwisolver-1.5.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0cbe94b69b819209a62cb27bdfa5dc2a8977d8de2f89dfd97ba4f53ed3af754e", size = 64063, upload-time = "2026-03-09T13:14:44.759Z" }, + { url = "https://files.pythonhosted.org/packages/e7/f9/b06c934a6aa8bc91f566bd2a214fd04c30506c2d9e2b6b171953216a65b6/kiwisolver-1.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:80aa065ffd378ff784822a6d7c3212f2d5f5e9c3589614b5c228b311fd3063ac", size = 1475913, upload-time = "2026-03-09T13:14:46.247Z" }, + { url = "https://files.pythonhosted.org/packages/6b/f0/f768ae564a710135630672981231320bc403cf9152b5596ec5289de0f106/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e7f886f47ab881692f278ae901039a234e4025a68e6dfab514263a0b1c4ae05", size = 1282782, upload-time = "2026-03-09T13:14:48.458Z" }, + { url = "https://files.pythonhosted.org/packages/e2/9f/1de7aad00697325f05238a5f2eafbd487fb637cc27a558b5367a5f37fb7f/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5060731cc3ed12ca3a8b57acd4aeca5bbc2f49216dd0bec1650a1acd89486bcd", size = 1300815, upload-time = "2026-03-09T13:14:50.721Z" }, + { url = "https://files.pythonhosted.org/packages/5a/c2/297f25141d2e468e0ce7f7a7b92e0cf8918143a0cbd3422c1ad627e85a06/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a4aa69609f40fce3cbc3f87b2061f042eee32f94b8f11db707b66a26461591a", size = 1347925, upload-time = "2026-03-09T13:14:52.304Z" }, + { url = "https://files.pythonhosted.org/packages/b9/d3/f4c73a02eb41520c47610207b21afa8cdd18fdbf64ffd94674ae21c4812d/kiwisolver-1.5.0-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:d168fda2dbff7b9b5f38e693182d792a938c31db4dac3a80a4888de603c99554", size = 991322, upload-time = "2026-03-09T13:14:54.637Z" }, + { url = "https://files.pythonhosted.org/packages/7b/46/d3f2efef7732fcda98d22bf4ad5d3d71d545167a852ca710a494f4c15343/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:413b820229730d358efd838ecbab79902fe97094565fdc80ddb6b0a18c18a581", size = 2232857, upload-time = "2026-03-09T13:14:56.471Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ec/2d9756bf2b6d26ae4349b8d3662fb3993f16d80c1f971c179ce862b9dbae/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5124d1ea754509b09e53738ec185584cc609aae4a3b510aaf4ed6aa047ef9303", size = 2329376, upload-time = "2026-03-09T13:14:58.072Z" }, + { url = "https://files.pythonhosted.org/packages/8f/9f/876a0a0f2260f1bde92e002b3019a5fabc35e0939c7d945e0fa66185eb20/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e4415a8db000bf49a6dd1c478bf70062eaacff0f462b92b0ba68791a905861f9", size = 1982549, upload-time = "2026-03-09T13:14:59.668Z" }, + { url = "https://files.pythonhosted.org/packages/6c/4f/ba3624dfac23a64d54ac4179832860cb537c1b0af06024936e82ca4154a0/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d618fd27420381a4f6044faa71f46d8bfd911bd077c555f7138ed88729bfbe79", size = 2494680, upload-time = "2026-03-09T13:15:01.364Z" }, + { url = "https://files.pythonhosted.org/packages/39/b7/97716b190ab98911b20d10bf92eca469121ec483b8ce0edd314f51bc85af/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5092eb5b1172947f57d6ea7d89b2f29650414e4293c47707eb499ec07a0ac796", size = 2297905, upload-time = "2026-03-09T13:15:03.925Z" }, + { url = "https://files.pythonhosted.org/packages/a3/36/4e551e8aa55c9188bca9abb5096805edbf7431072b76e2298e34fd3a3008/kiwisolver-1.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:d76e2d8c75051d58177e762164d2e9ab92886534e3a12e795f103524f221dd8e", size = 75086, upload-time = "2026-03-09T13:15:07.775Z" }, + { url = "https://files.pythonhosted.org/packages/70/15/9b90f7df0e31a003c71649cf66ef61c3c1b862f48c81007fa2383c8bd8d7/kiwisolver-1.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:fa6248cd194edff41d7ea9425ced8ca3a6f838bfb295f6f1d6e6bb694a8518df", size = 66577, upload-time = "2026-03-09T13:15:09.139Z" }, + { url = "https://files.pythonhosted.org/packages/17/01/7dc8c5443ff42b38e72731643ed7cf1ed9bf01691ae5cdca98501999ed83/kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d1ffeb80b5676463d7a7d56acbe8e37a20ce725570e09549fe738e02ca6b7e1e", size = 125794, upload-time = "2026-03-09T13:15:10.525Z" }, + { url = "https://files.pythonhosted.org/packages/46/8a/b4ebe46ebaac6a303417fab10c2e165c557ddaff558f9699d302b256bc53/kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc4d8e252f532ab46a1de9349e2d27b91fce46736a9eedaa37beaca66f574ed4", size = 67646, upload-time = "2026-03-09T13:15:12.016Z" }, + { url = "https://files.pythonhosted.org/packages/60/35/10a844afc5f19d6f567359bf4789e26661755a2f36200d5d1ed8ad0126e5/kiwisolver-1.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6783e069732715ad0c3ce96dbf21dbc2235ab0593f2baf6338101f70371f4028", size = 65511, upload-time = "2026-03-09T13:15:13.311Z" }, + { url = "https://files.pythonhosted.org/packages/f8/8a/685b297052dd041dcebce8e8787b58923b6e78acc6115a0dc9189011c44b/kiwisolver-1.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e7c4c09a490dc4d4a7f8cbee56c606a320f9dc28cf92a7157a39d1ce7676a657", size = 1584858, upload-time = "2026-03-09T13:15:15.103Z" }, + { url = "https://files.pythonhosted.org/packages/9e/80/04865e3d4638ac5bddec28908916df4a3075b8c6cc101786a96803188b96/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a075bd7bd19c70cf67c8badfa36cf7c5d8de3c9ddb8420c51e10d9c50e94920", size = 1392539, upload-time = "2026-03-09T13:15:16.661Z" }, + { url = "https://files.pythonhosted.org/packages/ba/01/77a19cacc0893fa13fafa46d1bba06fb4dc2360b3292baf4b56d8e067b24/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bdd3e53429ff02aa319ba59dfe4ceeec345bf46cf180ec2cf6fd5b942e7975e9", size = 1405310, upload-time = "2026-03-09T13:15:18.229Z" }, + { url = "https://files.pythonhosted.org/packages/53/39/bcaf5d0cca50e604cfa9b4e3ae1d64b50ca1ae5b754122396084599ef903/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cdcb35dc9d807259c981a85531048ede628eabcffb3239adf3d17463518992d", size = 1456244, upload-time = "2026-03-09T13:15:20.444Z" }, + { url = "https://files.pythonhosted.org/packages/d0/7a/72c187abc6975f6978c3e39b7cf67aeb8b3c0a8f9790aa7fd412855e9e1f/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:70d593af6a6ca332d1df73d519fddb5148edb15cd90d5f0155e3746a6d4fcc65", size = 1073154, upload-time = "2026-03-09T13:15:22.039Z" }, + { url = "https://files.pythonhosted.org/packages/c7/ca/cf5b25783ebbd59143b4371ed0c8428a278abe68d6d0104b01865b1bbd0f/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:377815a8616074cabbf3f53354e1d040c35815a134e01d7614b7692e4bf8acfa", size = 2334377, upload-time = "2026-03-09T13:15:23.741Z" }, + { url = "https://files.pythonhosted.org/packages/4a/e5/b1f492adc516796e88751282276745340e2a72dcd0d36cf7173e0daf3210/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0255a027391d52944eae1dbb5d4cc5903f57092f3674e8e544cdd2622826b3f0", size = 2425288, upload-time = "2026-03-09T13:15:25.789Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e5/9b21fbe91a61b8f409d74a26498706e97a48008bfcd1864373d32a6ba31c/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:012b1eb16e28718fa782b5e61dc6f2da1f0792ca73bd05d54de6cb9561665fc9", size = 2063158, upload-time = "2026-03-09T13:15:27.63Z" }, + { url = "https://files.pythonhosted.org/packages/b1/02/83f47986138310f95ea95531f851b2a62227c11cbc3e690ae1374fe49f0f/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0e3aafb33aed7479377e5e9a82e9d4bf87063741fc99fc7ae48b0f16e32bdd6f", size = 2597260, upload-time = "2026-03-09T13:15:29.421Z" }, + { url = "https://files.pythonhosted.org/packages/07/18/43a5f24608d8c313dd189cf838c8e68d75b115567c6279de7796197cfb6a/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e7a116ae737f0000343218c4edf5bd45893bfeaff0993c0b215d7124c9f77646", size = 2394403, upload-time = "2026-03-09T13:15:31.517Z" }, + { url = "https://files.pythonhosted.org/packages/3b/b5/98222136d839b8afabcaa943b09bd05888c2d36355b7e448550211d1fca4/kiwisolver-1.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:1dd9b0b119a350976a6d781e7278ec7aca0b201e1a9e2d23d9804afecb6ca681", size = 79687, upload-time = "2026-03-09T13:15:33.204Z" }, + { url = "https://files.pythonhosted.org/packages/99/a2/ca7dc962848040befed12732dff6acae7fb3c4f6fc4272b3f6c9a30b8713/kiwisolver-1.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:58f812017cd2985c21fbffb4864d59174d4903dd66fa23815e74bbc7a0e2dd57", size = 70032, upload-time = "2026-03-09T13:15:34.411Z" }, +] + +[[package]] +name = "llvmlite" +version = "0.47.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/88/a8952b6d5c21e74cbf158515b779666f692846502623e9e3c39d8e8ba25f/llvmlite-0.47.0.tar.gz", hash = "sha256:62031ce968ec74e95092184d4b0e857e444f8fdff0b8f9213707699570c33ccc", size = 193614, upload-time = "2026-03-31T18:29:53.497Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/d4/33c8af00f0bf6f552d74f3a054f648af2c5bc6bece97972f3bfadce4f5ec/llvmlite-0.47.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:de966c626c35c9dff5ae7bf12db25637738d0df83fc370cf793bc94d43d92d14", size = 37232773, upload-time = "2026-03-31T18:29:19.453Z" }, + { url = "https://files.pythonhosted.org/packages/64/1d/a760e993e0c0ba6db38d46b9f48f6c7dceb8ac838824997fb9e25f97bc04/llvmlite-0.47.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ddbccff2aeaff8670368340a158abefc032fe9b3ccf7d9c496639263d00151aa", size = 56275176, upload-time = "2026-03-31T18:29:24.149Z" }, + { url = "https://files.pythonhosted.org/packages/84/3b/e679bc3b29127182a7f4aa2d2e9e5bea42adb93fb840484147d59c236299/llvmlite-0.47.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4a7b778a2e144fc64468fb9bf509ac1226c9813a00b4d7afea5d988c4e22fca", size = 55128631, upload-time = "2026-03-31T18:29:29.536Z" }, + { url = "https://files.pythonhosted.org/packages/be/f7/19e2a09c62809c9e63bbd14ce71fb92c6ff7b7b3045741bb00c781efc3c9/llvmlite-0.47.0-cp314-cp314-win_amd64.whl", hash = "sha256:694e3c2cdc472ed2bd8bd4555ca002eec4310961dd58ef791d508f57b5cc4c94", size = 39153826, upload-time = "2026-03-31T18:29:33.681Z" }, + { url = "https://files.pythonhosted.org/packages/40/a1/581a8c707b5e80efdbbe1dd94527404d33fe50bceb71f39d5a7e11bd57b7/llvmlite-0.47.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:92ec8a169a20b473c1c54d4695e371bde36489fc1efa3688e11e99beba0abf9c", size = 37232772, upload-time = "2026-03-31T18:29:37.952Z" }, + { url = "https://files.pythonhosted.org/packages/11/03/16090dd6f74ba2b8b922276047f15962fbeea0a75d5601607edb301ba945/llvmlite-0.47.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fa1cbd800edd3b20bc141521f7fd45a6185a5b84109aa6855134e81397ffe72b", size = 56275178, upload-time = "2026-03-31T18:29:42.58Z" }, + { url = "https://files.pythonhosted.org/packages/f5/cb/0abf1dd4c5286a95ffe0c1d8c67aec06b515894a0dd2ac97f5e27b82ab0b/llvmlite-0.47.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f6725179b89f03b17dabe236ff3422cb8291b4c1bf40af152826dfd34e350ae8", size = 55128632, upload-time = "2026-03-31T18:29:46.939Z" }, + { url = "https://files.pythonhosted.org/packages/4f/79/d3bbab197e86e0ff4f9c07122895b66a3e0d024247fcff7f12c473cb36d9/llvmlite-0.47.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6842cf6f707ec4be3d985a385ad03f72b2d724439e118fcbe99b2929964f0453", size = 39153839, upload-time = "2026-03-31T18:29:51.004Z" }, +] + +[[package]] +name = "matplotlib" +version = "3.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "contourpy" }, + { name = "cycler" }, + { name = "fonttools" }, + { name = "kiwisolver" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pillow" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1f/24/080c99d223d158d3a8902769269ab6da5b50f7a0e6e072513907e02b7a6c/matplotlib-3.11.0.tar.gz", hash = "sha256:68c0c7be01b30dcca3638934f7f591df73401235cbdbf0d1ab1c71e7db7f8b57", size = 33251176, upload-time = "2026-06-12T02:29:15.508Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/52/a94102ac99eb78e2fe9b826674f9ef9ee23327110ea6ab4776c1b4eb6209/matplotlib-3.11.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3338e3e3de128cf50d0d2fb92a122815daf9c755bd882a474343c05f8fd7ec79", size = 9452137, upload-time = "2026-06-12T02:28:37.93Z" }, + { url = "https://files.pythonhosted.org/packages/7c/03/b8cdb625a21f710dfa11bbca1f48fb4057d2c0286975f8b415bf80942c99/matplotlib-3.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:25c2e5455efd8d99f41fb79871a31feb7d301569642e332ec58d72cfe9282bc3", size = 9281514, upload-time = "2026-06-12T02:28:40.028Z" }, + { url = "https://files.pythonhosted.org/packages/b7/2d/4e1240ea82ee197dfb3851e71f71c87eeeb975f1753b56a0588e4e80739a/matplotlib-3.11.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9695457a467ff86d23f35037a43deb6f1134dd6d3e2ac8ce1e2087cff09ffb9", size = 10843005, upload-time = "2026-06-12T02:28:42.39Z" }, + { url = "https://files.pythonhosted.org/packages/29/dc/6377ecfaa5fef79430f74a1a16638b4e2aa30d4692bae2c19f9d76fe3b01/matplotlib-3.11.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:19c16c61dea63b3582918503e6b294193961261d9daa806d4ae2151f1ad05430", size = 11127459, upload-time = "2026-06-12T02:28:44.483Z" }, + { url = "https://files.pythonhosted.org/packages/6f/41/795c405aa7560443a3b01309424cde4a1113b85c90b8a63417444a749617/matplotlib-3.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2d72ea8b7924f3cb955e61518d21e43b3df1e6c8a793b480a0c1214f185d30ba", size = 10925160, upload-time = "2026-06-12T02:28:46.564Z" }, + { url = "https://files.pythonhosted.org/packages/1a/f7/3a9e6389a7cfaeff76c56e40c2dabcb13110e21e82f837228c834ebe748c/matplotlib-3.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:1c02da0a629dfa9debf52725ea06866b74c1fb70a895bae05e4493d34074f9f2", size = 9485186, upload-time = "2026-06-12T02:28:49.344Z" }, + { url = "https://files.pythonhosted.org/packages/8b/c0/396478ee7cf2091d182db8b4a8695f6a37f1ddb978989cf9dbb84cd5c123/matplotlib-3.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:aa55d73b3117d4b07f959cd9eb6f69b375d8df3414139c479388e551aa5d999d", size = 9160349, upload-time = "2026-06-12T02:28:51.382Z" }, + { url = "https://files.pythonhosted.org/packages/c5/6f/1c3bd51bb2b34eaacdcf3c3d859dbb357f952fc8020c617dc118ad7c9e38/matplotlib-3.11.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:a9d8c6e7cd2f0ddf11d8d92e520dd1d9d2abb0cf6ac8831e338666c81e905847", size = 9500921, upload-time = "2026-06-12T02:28:53.443Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0d/4d861d0121840cb1a3fd4a10deb211efd6fccd481ed23e553f31f4f4da4a/matplotlib-3.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:be050fcf32f729eda99f7f75a80bf67612ce16ab9ac1c23a387dcaede95cb70e", size = 9332190, upload-time = "2026-06-12T02:28:55.623Z" }, + { url = "https://files.pythonhosted.org/packages/4b/cb/22f6bc35711a0b5639a784e74e653e77c86210bd4304449dd399a482f74e/matplotlib-3.11.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dfabef0230d0697aa0d717385194dd41162e00207a68bf4abf94c2bf4c27dca0", size = 10854181, upload-time = "2026-06-12T02:28:57.856Z" }, + { url = "https://files.pythonhosted.org/packages/3f/7e/9a9eaca731a2939589da520f0ebe8fd8753d0f51fca98c7d20af6dbe261a/matplotlib-3.11.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1644db30e759199443493ac5e5caec24fdb775a8f6123021f85ba47c4133c3cb", size = 11137715, upload-time = "2026-06-12T02:29:00.555Z" }, + { url = "https://files.pythonhosted.org/packages/ef/f9/9b030b6088354acb0296871bb624b25befc1c42509d3c6cd17420c83a5b8/matplotlib-3.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:15b0d160079cb10699a0e98b5989c70677b2df7cacdc62af67c30f2facec46d9", size = 10939427, upload-time = "2026-06-12T02:29:02.527Z" }, + { url = "https://files.pythonhosted.org/packages/59/94/6b273eaee4ee250863567d100865da61a5c1527fa67f527b7ed22e0dd29c/matplotlib-3.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:446307e6b04b57b1f1239e228a1ec2af0d589a1008cebc3dfa3f5441d095cfb6", size = 9535809, upload-time = "2026-06-12T02:29:04.994Z" }, + { url = "https://files.pythonhosted.org/packages/60/95/1d36bddf2b7e2692c1540e78a6e5bc88bc1496b137e3e35a611f91b65ac3/matplotlib-3.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:652fb5696271d4c50f196d22a5ff4f8e4444c74f847423570d7dc0aa2bbd0159", size = 9209226, upload-time = "2026-06-12T02:29:07.033Z" }, +] + +[[package]] +name = "mccabe" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", size = 9658, upload-time = "2022-01-24T01:14:51.113Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350, upload-time = "2022-01-24T01:14:49.62Z" }, +] + +[[package]] +name = "mpmath" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, +] + +[[package]] +name = "narwhals" +version = "2.22.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/62/3c/c4ef2164a71c1a63d7f1ae411c4082c5fa872405106db60a4b7114989ad7/narwhals-2.22.1.tar.gz", hash = "sha256:d62920805a0a43b7ff8b54b0c0d3142d796f8a9301836ada37e573d6a33cbcd9", size = 647493, upload-time = "2026-06-05T12:34:34.051Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/ca/36339329c4604adbcc99c899b7eb1ce1a555c499b6a6860757dc9bfed36d/narwhals-2.22.1-py3-none-any.whl", hash = "sha256:60567d774edf77db53906f89d9fbd164e66e56d66d388e1e6990f17ac33cfb53", size = 454815, upload-time = "2026-06-05T12:34:32.289Z" }, +] + +[[package]] +name = "networkx" +version = "3.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/51/63fe664f3908c97be9d2e4f1158eb633317598cfa6e1fc14af5383f17512/networkx-3.6.1.tar.gz", hash = "sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509", size = 2517025, upload-time = "2025-12-08T17:02:39.908Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504, upload-time = "2025-12-08T17:02:38.159Z" }, +] + +[[package]] +name = "numba" +version = "0.65.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llvmlite" }, + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f6/c5/db2ac3685833d626c0dcae6bd2330cd68433e1fd248d15f70998160d3ad7/numba-0.65.1.tar.gz", hash = "sha256:19357146c32fe9ed25059ab915e8465fb13951cf6b0aace3826b76886373ab23", size = 2765600, upload-time = "2026-04-24T02:02:56.551Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4f/2e/8aed9b726d9ba5f11ad287645fd479e88278db3060a25cb1225d730eb2b7/numba-0.65.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:33f5eb68eb1c843511615d14663ce60258525d6a4c65ab040e2c2b0c4cf17450", size = 2681554, upload-time = "2026-04-24T02:02:41.812Z" }, + { url = "https://files.pythonhosted.org/packages/87/96/f3eb235fafa82a34e2ab5dd7dc9ffff998ebf5f0bbc23fa56a96aeb44da6/numba-0.65.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:71e73029bf53a62cc6afcf96be4bd942290d8b4c55f0a454fb536158115790f7", size = 3779602, upload-time = "2026-04-24T02:02:43.726Z" }, + { url = "https://files.pythonhosted.org/packages/09/90/b0f09b48752d23640b8284f22aa597737e8adaddc7fbfacc4708b7f73a4c/numba-0.65.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a07635e0be926b9bdbffb09137c230fb13f6ec0e564914ba937cee12ce3eb35", size = 3479532, upload-time = "2026-04-24T02:02:45.427Z" }, + { url = "https://files.pythonhosted.org/packages/56/46/3f7fc04fb853559e74b210e0b62c19974ec844cefec611f9e535f4da3761/numba-0.65.1-cp314-cp314-win_amd64.whl", hash = "sha256:2a20fcdabdefbdacf88d85caf70c3b18c4bcb7ebb8f82e6a19486383dd26ab63", size = 2752637, upload-time = "2026-04-24T02:02:47.664Z" }, + { url = "https://files.pythonhosted.org/packages/81/7b/c1a341a9067367778f4152a5f01061cf281fb09582c92c510ec4918cabf6/numba-0.65.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:548dd4b3a4508d5062768d1514b2cd7b015f9a25ec7af651c50dee243965e652", size = 2684600, upload-time = "2026-04-24T02:02:49.653Z" }, + { url = "https://files.pythonhosted.org/packages/03/36/98ddbcf3e4f04a6dd07e1c67249955920579ba4af6bb6868e3088f4ed282/numba-0.65.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:78abc28feff2c2ff8307fff3975b6438352759c9acb797ecd6b1fb6e7e39e31d", size = 3817198, upload-time = "2026-04-24T02:02:51.266Z" }, + { url = "https://files.pythonhosted.org/packages/a3/83/0dad21057ece5a835599f5d24099b091703995e23dbbf894f259e91c010b/numba-0.65.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee7676cb389555805f9b9a1840cbcd1ea6c8bd5376ab6918e3a29c5ea1dbda20", size = 3533862, upload-time = "2026-04-24T02:02:52.987Z" }, + { url = "https://files.pythonhosted.org/packages/32/36/8be7118ffd4c8440881046eac3d0982cc5ab42909508cf5d67024d62a2e4/numba-0.65.1-cp314-cp314t-win_amd64.whl", hash = "sha256:20609346e3bd75204950dcbbfe383a8d7dbf4902f442aedbf00f97fef4aa8f38", size = 2758237, upload-time = "2026-04-24T02:02:54.612Z" }, +] + +[[package]] +name = "numpy" +version = "2.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/91/3ab2044d05fd16d343c5ac2e69b127f1b2854040dd20b193257c78028bd3/numpy-2.4.6-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079", size = 16683458, upload-time = "2026-05-18T23:35:38.353Z" }, + { url = "https://files.pythonhosted.org/packages/8e/62/764ce66fa4147ae6d73071a3abf804ffe606f174618697c571acdf26a7c9/numpy-2.4.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7", size = 14704559, upload-time = "2026-05-18T23:35:42.14Z" }, + { url = "https://files.pythonhosted.org/packages/60/61/23f27c172f022e04025b7dc2367f4d63c1a398120607ec896228649a6f48/numpy-2.4.6-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5", size = 5209716, upload-time = "2026-05-18T23:35:45.377Z" }, + { url = "https://files.pythonhosted.org/packages/03/71/21cf70dc6ea3e3acb95fc53a265b2fc248b981f0194ceb5b475271b8809d/numpy-2.4.6-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096", size = 6543947, upload-time = "2026-05-18T23:35:47.926Z" }, + { url = "https://files.pythonhosted.org/packages/d5/91/64288395ee1799bd2e0b04a305dce9666da90c961e1f3fe982a05ee1c036/numpy-2.4.6-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b", size = 15685197, upload-time = "2026-05-18T23:35:50.863Z" }, + { url = "https://files.pythonhosted.org/packages/f3/eb/ebffaa97dc55502df69584a8f0dcf07f69a3e0b3e2323670a2722db9aa39/numpy-2.4.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8", size = 16638245, upload-time = "2026-05-18T23:35:54.752Z" }, + { url = "https://files.pythonhosted.org/packages/b8/0b/54f9da33128d7e350fab89c7455902eeae70349ee52bddb448dc4a576f45/numpy-2.4.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402", size = 17036587, upload-time = "2026-05-18T23:35:58.355Z" }, + { url = "https://files.pythonhosted.org/packages/b6/f0/fdebc1052db1cc37c64beb22072d67cd6d1c71adca1299f53dec2b5e20d3/numpy-2.4.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb", size = 18363226, upload-time = "2026-05-18T23:36:02.845Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b4/298628d98c72b57e57f7165ae6a481a1deaf6f3c28262a6e4c739c275930/numpy-2.4.6-cp314-cp314-win32.whl", hash = "sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1", size = 6010196, upload-time = "2026-05-18T23:36:05.92Z" }, + { url = "https://files.pythonhosted.org/packages/df/ac/46de6dda46478f7942f839e094970be2d4a861e005c4b3bf07c92e291a09/numpy-2.4.6-cp314-cp314-win_amd64.whl", hash = "sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261", size = 12450334, upload-time = "2026-05-18T23:36:09.107Z" }, + { url = "https://files.pythonhosted.org/packages/78/92/b8b798ac784102c0da830d2257d59358e3d3d90d1e2b3f2575dad976c5cf/numpy-2.4.6-cp314-cp314-win_arm64.whl", hash = "sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6", size = 10495678, upload-time = "2026-05-18T23:36:12.766Z" }, + { url = "https://files.pythonhosted.org/packages/30/34/ec28d1aa8115971537c01469ab2011ee96827930f0a124de1000cc2a7ed7/numpy-2.4.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a", size = 14823672, upload-time = "2026-05-18T23:36:16.473Z" }, + { url = "https://files.pythonhosted.org/packages/16/bd/f6d1fede4e54e8042a7ff97bb495510f3c220f94bcd9e8b228e87c92cc0d/numpy-2.4.6-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e", size = 5328731, upload-time = "2026-05-18T23:36:19.767Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f0/e105b9e2fd728a9910103884decd6951d9dd73896b914a98d9a231de02ee/numpy-2.4.6-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e", size = 6649805, upload-time = "2026-05-18T23:36:22.266Z" }, + { url = "https://files.pythonhosted.org/packages/82/dd/1206a7ca6ab15e3f02069707ca96222e202af681bb73756da7527f3cb837/numpy-2.4.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43", size = 15730496, upload-time = "2026-05-18T23:36:25.713Z" }, + { url = "https://files.pythonhosted.org/packages/51/e7/38d3ea825dcab85a591734decb2f6c67caa7c8367d374df1a1c3842f9b07/numpy-2.4.6-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e", size = 16679616, upload-time = "2026-05-18T23:36:29.652Z" }, + { url = "https://files.pythonhosted.org/packages/93/b7/caabfdf53edf663e0b4eb74d7d405d83baef09eb5e83bcd32d601d72b93e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895", size = 17085145, upload-time = "2026-05-18T23:36:33.449Z" }, + { url = "https://files.pythonhosted.org/packages/f9/45/68d7c33a6bcf3e5aa3bdbd57a367e6f615286dfd6482f97e8ffeb734306e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4", size = 18403813, upload-time = "2026-05-18T23:36:37.369Z" }, + { url = "https://files.pythonhosted.org/packages/9c/50/0753655aa844c99cd9e018aacf76f130f1bd81d881bb74bc0aef5d73a8ba/numpy-2.4.6-cp314-cp314t-win32.whl", hash = "sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063", size = 6156982, upload-time = "2026-05-18T23:36:40.817Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d4/7c67becf668f973cb490cec3e98dfd799d866f9c989a54d355672cfa0db6/numpy-2.4.6-cp314-cp314t-win_amd64.whl", hash = "sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627", size = 12638908, upload-time = "2026-05-18T23:36:43.996Z" }, + { url = "https://files.pythonhosted.org/packages/43/bb/e1c71a4295b1b1d1393d50dbb4f2a36283c6859d9d3892e84f00ec5a91d5/numpy-2.4.6-cp314-cp314t-win_arm64.whl", hash = "sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66", size = 10565867, upload-time = "2026-05-18T23:36:47.114Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pillow" +version = "12.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/21/c2bcdd5906101a30244eaffc1b6e6ce71a31bd0742a01eb89e660ebfac2d/pillow-12.2.0.tar.gz", hash = "sha256:a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5", size = 46987819, upload-time = "2026-04-01T14:46:17.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/98/4595daa2365416a86cb0d495248a393dfc84e96d62ad080c8546256cb9c0/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:3adc9215e8be0448ed6e814966ecf3d9952f0ea40eb14e89a102b87f450660d8", size = 4100848, upload-time = "2026-04-01T14:44:48.48Z" }, + { url = "https://files.pythonhosted.org/packages/0b/79/40184d464cf89f6663e18dfcf7ca21aae2491fff1a16127681bf1fa9b8cf/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:6a9adfc6d24b10f89588096364cc726174118c62130c817c2837c60cf08a392b", size = 4176515, upload-time = "2026-04-01T14:44:51.353Z" }, + { url = "https://files.pythonhosted.org/packages/b0/63/703f86fd4c422a9cf722833670f4f71418fb116b2853ff7da722ea43f184/pillow-12.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:6a6e67ea2e6feda684ed370f9a1c52e7a243631c025ba42149a2cc5934dec295", size = 3640159, upload-time = "2026-04-01T14:44:53.588Z" }, + { url = "https://files.pythonhosted.org/packages/71/e0/fb22f797187d0be2270f83500aab851536101b254bfa1eae10795709d283/pillow-12.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2bb4a8d594eacdfc59d9e5ad972aa8afdd48d584ffd5f13a937a664c3e7db0ed", size = 5312185, upload-time = "2026-04-01T14:44:56.039Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8c/1a9e46228571de18f8e28f16fabdfc20212a5d019f3e3303452b3f0a580d/pillow-12.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:80b2da48193b2f33ed0c32c38140f9d3186583ce7d516526d462645fd98660ae", size = 4695386, upload-time = "2026-04-01T14:44:58.663Z" }, + { url = "https://files.pythonhosted.org/packages/70/62/98f6b7f0c88b9addd0e87c217ded307b36be024d4ff8869a812b241d1345/pillow-12.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22db17c68434de69d8ecfc2fe821569195c0c373b25cccb9cbdacf2c6e53c601", size = 6280384, upload-time = "2026-04-01T14:45:01.5Z" }, + { url = "https://files.pythonhosted.org/packages/5e/03/688747d2e91cfbe0e64f316cd2e8005698f76ada3130d0194664174fa5de/pillow-12.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7b14cc0106cd9aecda615dd6903840a058b4700fcb817687d0ee4fc8b6e389be", size = 8091599, upload-time = "2026-04-01T14:45:04.5Z" }, + { url = "https://files.pythonhosted.org/packages/f6/35/577e22b936fcdd66537329b33af0b4ccfefaeabd8aec04b266528cddb33c/pillow-12.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cbeb542b2ebc6fcdacabf8aca8c1a97c9b3ad3927d46b8723f9d4f033288a0f", size = 6396021, upload-time = "2026-04-01T14:45:07.117Z" }, + { url = "https://files.pythonhosted.org/packages/11/8d/d2532ad2a603ca2b93ad9f5135732124e57811d0168155852f37fbce2458/pillow-12.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4bfd07bc812fbd20395212969e41931001fd59eb55a60658b0e5710872e95286", size = 7083360, upload-time = "2026-04-01T14:45:09.763Z" }, + { url = "https://files.pythonhosted.org/packages/5e/26/d325f9f56c7e039034897e7380e9cc202b1e368bfd04d4cbe6a441f02885/pillow-12.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9aba9a17b623ef750a4d11b742cbafffeb48a869821252b30ee21b5e91392c50", size = 6507628, upload-time = "2026-04-01T14:45:12.378Z" }, + { url = "https://files.pythonhosted.org/packages/5f/f7/769d5632ffb0988f1c5e7660b3e731e30f7f8ec4318e94d0a5d674eb65a4/pillow-12.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:deede7c263feb25dba4e82ea23058a235dcc2fe1f6021025dc71f2b618e26104", size = 7209321, upload-time = "2026-04-01T14:45:15.122Z" }, + { url = "https://files.pythonhosted.org/packages/6a/7a/c253e3c645cd47f1aceea6a8bacdba9991bf45bb7dfe927f7c893e89c93c/pillow-12.2.0-cp314-cp314-win32.whl", hash = "sha256:632ff19b2778e43162304d50da0181ce24ac5bb8180122cbe1bf4673428328c7", size = 6479723, upload-time = "2026-04-01T14:45:17.797Z" }, + { url = "https://files.pythonhosted.org/packages/cd/8b/601e6566b957ca50e28725cb6c355c59c2c8609751efbecd980db44e0349/pillow-12.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:4e6c62e9d237e9b65fac06857d511e90d8461a32adcc1b9065ea0c0fa3a28150", size = 7217400, upload-time = "2026-04-01T14:45:20.529Z" }, + { url = "https://files.pythonhosted.org/packages/d6/94/220e46c73065c3e2951bb91c11a1fb636c8c9ad427ac3ce7d7f3359b9b2f/pillow-12.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:b1c1fbd8a5a1af3412a0810d060a78b5136ec0836c8a4ef9aa11807f2a22f4e1", size = 2554835, upload-time = "2026-04-01T14:45:23.162Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ab/1b426a3974cb0e7da5c29ccff4807871d48110933a57207b5a676cccc155/pillow-12.2.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:57850958fe9c751670e49b2cecf6294acc99e562531f4bd317fa5ddee2068463", size = 5314225, upload-time = "2026-04-01T14:45:25.637Z" }, + { url = "https://files.pythonhosted.org/packages/19/1e/dce46f371be2438eecfee2a1960ee2a243bbe5e961890146d2dee1ff0f12/pillow-12.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d5d38f1411c0ed9f97bcb49b7bd59b6b7c314e0e27420e34d99d844b9ce3b6f3", size = 4698541, upload-time = "2026-04-01T14:45:28.355Z" }, + { url = "https://files.pythonhosted.org/packages/55/c3/7fbecf70adb3a0c33b77a300dc52e424dc22ad8cdc06557a2e49523b703d/pillow-12.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5c0a9f29ca8e79f09de89293f82fc9b0270bb4af1d58bc98f540cc4aedf03166", size = 6322251, upload-time = "2026-04-01T14:45:30.924Z" }, + { url = "https://files.pythonhosted.org/packages/1c/3c/7fbc17cfb7e4fe0ef1642e0abc17fc6c94c9f7a16be41498e12e2ba60408/pillow-12.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1610dd6c61621ae1cf811bef44d77e149ce3f7b95afe66a4512f8c59f25d9ebe", size = 8127807, upload-time = "2026-04-01T14:45:33.908Z" }, + { url = "https://files.pythonhosted.org/packages/ff/c3/a8ae14d6defd2e448493ff512fae903b1e9bd40b72efb6ec55ce0048c8ce/pillow-12.2.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a34329707af4f73cf1782a36cd2289c0368880654a2c11f027bcee9052d35dd", size = 6433935, upload-time = "2026-04-01T14:45:36.623Z" }, + { url = "https://files.pythonhosted.org/packages/6e/32/2880fb3a074847ac159d8f902cb43278a61e85f681661e7419e6596803ed/pillow-12.2.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e9c4f5b3c546fa3458a29ab22646c1c6c787ea8f5ef51300e5a60300736905e", size = 7116720, upload-time = "2026-04-01T14:45:39.258Z" }, + { url = "https://files.pythonhosted.org/packages/46/87/495cc9c30e0129501643f24d320076f4cc54f718341df18cc70ec94c44e1/pillow-12.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fb043ee2f06b41473269765c2feae53fc2e2fbf96e5e22ca94fb5ad677856f06", size = 6540498, upload-time = "2026-04-01T14:45:41.879Z" }, + { url = "https://files.pythonhosted.org/packages/18/53/773f5edca692009d883a72211b60fdaf8871cbef075eaa9d577f0a2f989e/pillow-12.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f278f034eb75b4e8a13a54a876cc4a5ab39173d2cdd93a638e1b467fc545ac43", size = 7239413, upload-time = "2026-04-01T14:45:44.705Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e4/4b64a97d71b2a83158134abbb2f5bd3f8a2ea691361282f010998f339ec7/pillow-12.2.0-cp314-cp314t-win32.whl", hash = "sha256:6bb77b2dcb06b20f9f4b4a8454caa581cd4dd0643a08bacf821216a16d9c8354", size = 6482084, upload-time = "2026-04-01T14:45:47.568Z" }, + { url = "https://files.pythonhosted.org/packages/ba/13/306d275efd3a3453f72114b7431c877d10b1154014c1ebbedd067770d629/pillow-12.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6562ace0d3fb5f20ed7290f1f929cae41b25ae29528f2af1722966a0a02e2aa1", size = 7225152, upload-time = "2026-04-01T14:45:50.032Z" }, + { url = "https://files.pythonhosted.org/packages/ff/6e/cf826fae916b8658848d7b9f38d88da6396895c676e8086fc0988073aaf8/pillow-12.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:aa88ccfe4e32d362816319ed727a004423aab09c5cea43c01a4b435643fa34eb", size = 2556579, upload-time = "2026-04-01T14:45:52.529Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/47/e4501f49c178ae1d9f4a75073fda4204f52647993f075a9db4d14930e0c5/platformdirs-4.10.0.tar.gz", hash = "sha256:31e761a6a0ca04faf7353ea759bdba55652be214725111e5aac52dfa29d4bef7", size = 31224, upload-time = "2026-05-28T03:32:53.587Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/e6/cd9575ac904136b3cbf7aa7ee819ef86eedb7274e46f230e94ea4342e729/platformdirs-4.10.0-py3-none-any.whl", hash = "sha256:fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a", size = 22743, upload-time = "2026-05-28T03:32:52.175Z" }, +] + +[[package]] +name = "plotly" +version = "6.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "narwhals" }, + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/94/fd/d72c292d78aadb93d1a9bcd76bf3c678271040c7cf10abe5788b33040a39/plotly-6.8.0.tar.gz", hash = "sha256:e088e7ddc68d4f70e3d66659224727a45296d71d2b8284181862d3d8f1f0d88f", size = 6915161, upload-time = "2026-06-03T18:33:40.226Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/14/abe5ce876ab5b66ee3c691bf537fcd43d037aea55d447aacf74630a8f31e/plotly-6.8.0-py3-none-any.whl", hash = "sha256:13c5c4a0f70b74cab1913eda0de49b826df5931708eb6f9c3010040614700ec8", size = 9902055, upload-time = "2026-06-03T18:33:34.26Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "profilehooks" +version = "1.13.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/5a/c69fdf542b730c74b9de1cc2cc02692cd5d6a34a9d95e29217262937f91e/profilehooks-1.13.0.tar.gz", hash = "sha256:54a541cad49ddccee97b61a617404d7d736bf0bf79d36fbe2ac7caa3a1d9daaf", size = 17695, upload-time = "2024-10-09T13:20:22.778Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/28/1c526d6cdbeb56aec99c5ec3920ffd7c5b002dbbafb387ebfb33678a1b95/profilehooks-1.13.0-py3-none-any.whl", hash = "sha256:869f63862b3d85e8af44ad7eb01a00203cc7a27a376ed3a51e409399062659c6", size = 10801, upload-time = "2024-10-09T13:20:21.445Z" }, +] + +[[package]] +name = "pycodestyle" +version = "2.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/e0/abfd2a0d2efe47670df87f3e3a0e2edda42f055053c85361f19c0e2c1ca8/pycodestyle-2.14.0.tar.gz", hash = "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783", size = 39472, upload-time = "2025-06-20T18:49:48.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl", hash = "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d", size = 31594, upload-time = "2025-06-20T18:49:47.491Z" }, +] + +[[package]] +name = "pycopan-more" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "matplotlib" }, + { name = "networkx" }, + { name = "numba" }, + { name = "numpy" }, + { name = "plotly" }, + { name = "profilehooks" }, + { name = "pycopancore" }, + { name = "pytest-cov" }, + { name = "python-louvain" }, + { name = "scipy" }, + { name = "sympy" }, +] + +[package.optional-dependencies] +dev = [ + { name = "pylama" }, + { name = "pylama-pylint" }, + { name = "pylint" }, +] + +[package.metadata] +requires-dist = [ + { name = "matplotlib", specifier = ">=3.11.0" }, + { name = "networkx", specifier = ">=3.6.1" }, + { name = "numba" }, + { name = "numpy", specifier = ">=1.11.0" }, + { name = "plotly", specifier = ">=6.8.0" }, + { name = "profilehooks" }, + { name = "pycopancore", git = "https://github.com/pik-copan/pycopancore.git" }, + { name = "pylama", marker = "extra == 'dev'" }, + { name = "pylama-pylint", marker = "extra == 'dev'" }, + { name = "pylint", marker = "extra == 'dev'" }, + { name = "pytest-cov", specifier = ">=2.5.1" }, + { name = "python-louvain", specifier = ">=0.9" }, + { name = "scipy", specifier = ">=0.17.0" }, + { name = "sympy", specifier = ">=1.0" }, +] +provides-extras = ["dev"] + +[[package]] +name = "pycopancore" +version = "0.8.6.dev13" +source = { git = "https://github.com/pik-copan/pycopancore.git#065ff75db103f1335a2079428d31a9a42d9b54f3" } +dependencies = [ + { name = "numba" }, + { name = "numpy" }, + { name = "profilehooks" }, + { name = "python-louvain" }, + { name = "scipy" }, + { name = "sympy" }, +] + +[[package]] +name = "pydocstyle" +version = "6.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "snowballstemmer" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/5c/d5385ca59fd065e3c6a5fe19f9bc9d5ea7f2509fa8c9c22fb6b2031dd953/pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1", size = 36796, upload-time = "2023-01-17T20:29:19.838Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/ea/99ddefac41971acad68f14114f38261c1f27dac0b3ec529824ebc739bdaa/pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019", size = 38038, upload-time = "2023-01-17T20:29:18.094Z" }, +] + +[[package]] +name = "pyflakes" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/45/dc/fd034dc20b4b264b3d015808458391acbf9df40b1e54750ef175d39180b1/pyflakes-3.4.0.tar.gz", hash = "sha256:b24f96fafb7d2ab0ec5075b7350b3d2d2218eab42003821c06344973d3ea2f58", size = 64669, upload-time = "2025-06-20T18:45:27.834Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/2f/81d580a0fb83baeb066698975cb14a618bdbed7720678566f1b046a95fe8/pyflakes-3.4.0-py2.py3-none-any.whl", hash = "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f", size = 63551, upload-time = "2025-06-20T18:45:26.937Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pylama" +version = "8.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mccabe" }, + { name = "pycodestyle" }, + { name = "pydocstyle" }, + { name = "pyflakes" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bf/4f/b6e14fa7fcc805bdfc970c2505535722bcfac7d2a2ad4da826f4865dc0ef/pylama-8.4.1.tar.gz", hash = "sha256:2d4f7aecfb5b7466216d48610c7d6bad1c3990c29cdd392ad08259b161e486f6", size = 33616, upload-time = "2022-08-08T11:27:28.752Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/3c/11be5c276f593f70d858db28e913449af76f07a1fb60612ef4131edc4527/pylama-8.4.1-py3-none-any.whl", hash = "sha256:5bbdbf5b620aba7206d688ed9fc917ecd3d73e15ec1a89647037a09fa3a86e60", size = 33151, upload-time = "2022-08-08T11:27:26.957Z" }, +] + +[[package]] +name = "pylama-pylint" +version = "3.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pylama" }, + { name = "pylint" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4e/ce/cd748c0653d2008e2b335e9cfd7146d22311e212adb0f8e3e02ad7c6e57a/pylama_pylint-3.1.1.tar.gz", hash = "sha256:c17833da77cf2e7f12948ed4cedaf89b78b6c79e0c5efb96d11af16fb86b9c5f", size = 4573, upload-time = "2018-10-05T11:17:27.281Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/d0/cb5f13775d2aa2bcedde811b1b6a93211f880fe1cd92c9f5a736b10e791b/pylama_pylint-3.1.1-py2.py3-none-any.whl", hash = "sha256:56ee65f344760a606d34b6384696fee42fa1a9ef5a14c760230d47cc2da60d52", size = 4891, upload-time = "2018-10-05T11:17:30.423Z" }, +] + +[[package]] +name = "pylint" +version = "4.0.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astroid" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "dill" }, + { name = "isort" }, + { name = "mccabe" }, + { name = "platformdirs" }, + { name = "tomlkit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/1d/3bb57f303701549550d74bf7ced2b07412be97125c167a0c9d216aa9f762/pylint-4.0.6.tar.gz", hash = "sha256:52f19191bee08bf103f9705ad1a0ece4aa5a0a4ef2bdcbd969375a1e6f6579d5", size = 1585588, upload-time = "2026-06-14T14:43:26.772Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/da/acb2e7d4dbd2dfb792d38c0d850481f29ad7049b356d23f56c687d35203b/pylint-4.0.6-py3-none-any.whl", hash = "sha256:d11a0e1fdb7b1cd46ec5d6fc78fee8b95f28695b2d6140e5809925f61e32ea54", size = 538389, upload-time = "2026-06-14T14:43:24.873Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "pytest-cov" +version = "7.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage" }, + { name = "pluggy" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/51/a849f96e117386044471c8ec2bd6cfebacda285da9525c9106aeb28da671/pytest_cov-7.1.0.tar.gz", hash = "sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2", size = 55592, upload-time = "2026-03-21T20:11:16.284Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "python-louvain" +version = "0.16" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "networkx" }, + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7c/0d/8787b021d52eb8764c0bb18ab95f720cf554902044c6a5cb1865daf45763/python-louvain-0.16.tar.gz", hash = "sha256:b7ba2df5002fd28d3ee789a49532baad11fe648e4f2117cf0798e7520a1da56b", size = 204641, upload-time = "2022-01-29T15:53:03.532Z" } + +[[package]] +name = "scipy" +version = "1.18.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/25/c2700dfaf6442b4effaa91af24ebce5dc9d31bb4a69706313aae70d72cd0/scipy-1.18.0.tar.gz", hash = "sha256:67b2ad2ad54c72ca6d04975a9b2df8c3638c34ddd5b28738e94fc2b57929d378", size = 30774447, upload-time = "2026-06-19T15:01:43.456Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b5/915a19b3de2f7430062b509653563db1633ddbb6f021b06731521115d4e2/scipy-1.18.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:4c256ee70c0d1a8a2ace807e199ccd4e3f57037433842abb3fb36bc17eaa9578", size = 31036253, upload-time = "2026-06-19T15:00:43.216Z" }, + { url = "https://files.pythonhosted.org/packages/d7/88/b72def7262e150d16be13fca37a96481138d624e700340bc3362a7588929/scipy-1.18.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:2ef3abc54a4ffc53765374b0d5728532dfdd2585ed23f6b11c206a1f0b1b9af8", size = 28673758, upload-time = "2026-06-19T15:00:46.663Z" }, + { url = "https://files.pythonhosted.org/packages/91/02/2e636a61a525632c373cf6a9c24442a3ffb79e364d38e98b32042964ac32/scipy-1.18.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:f2a6af57bd9e4a75d70e4117e78a1bbee84f79ae3fbb6d0111005d6ebcc4cb8d", size = 20415514, upload-time = "2026-06-19T15:00:49.399Z" }, + { url = "https://files.pythonhosted.org/packages/c9/b6/2135974442f6aba159d9d39d774a1c8cb19947016725d69fecc685df45bf/scipy-1.18.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:3f1ac564d3bf6c03d861d2cd87a1bea0da2887136f7fb1bf519c05a8971452d6", size = 23034398, upload-time = "2026-06-19T15:00:51.941Z" }, + { url = "https://files.pythonhosted.org/packages/f6/e6/ba89ec5abf6ee9257c0d1ec985573f3ae32742c24bc03e016388a40b1b15/scipy-1.18.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40395a5fcd1abee49a5c7aaa98c29db393eedc835138560a588c47ec16156690", size = 33998032, upload-time = "2026-06-19T15:00:54.838Z" }, + { url = "https://files.pythonhosted.org/packages/7f/c4/bc41eb19b0fd0db868f4132920879019318d80cc522ad8f2bca4611af808/scipy-1.18.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ca01e8ae69f1b18e9a58d91afead31be3cef0dd905a10249dac559ee15460a0", size = 35283333, upload-time = "2026-06-19T15:00:58.152Z" }, + { url = "https://files.pythonhosted.org/packages/53/a4/cbdeef6eb3830a8462a9d4ada814de5fc984345cc9ecf17cbec51a036f1e/scipy-1.18.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7a7f3b01647384dbc3a711e8c6778e0aabbe93959249fef5c7393396bcac0867", size = 35610216, upload-time = "2026-06-19T15:01:01.155Z" }, + { url = "https://files.pythonhosted.org/packages/80/4d/b2b82502b65f661d1b789c1665dcdf315d5f12194e06fc0b37946294ebae/scipy-1.18.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6aa94e78ec192a30063a5e72e561c28af769dc311190b24fe91774eff1969709", size = 37418960, upload-time = "2026-06-19T15:01:04.155Z" }, + { url = "https://files.pythonhosted.org/packages/93/3e/902d836831474b0ab5a37d16404f7bc5fafd9efba632890e271ba952635f/scipy-1.18.0-cp314-cp314-win_amd64.whl", hash = "sha256:2d8bbdc6c817f5b4006a54d799d4f5bab6f910193cbb9a1ff310833d4d270f61", size = 37288845, upload-time = "2026-06-19T15:01:07.822Z" }, + { url = "https://files.pythonhosted.org/packages/b6/43/8d73b337a3bdb14daa0314f0434210747c02d79d729ce1777574a817dcf6/scipy-1.18.0-cp314-cp314-win_arm64.whl", hash = "sha256:18e9575f1569b2c54174e6159d32942e03731177f63dce7975f0a0c88d102f5b", size = 24988971, upload-time = "2026-06-19T15:01:11.076Z" }, + { url = "https://files.pythonhosted.org/packages/b4/b4/f11918b0508a2787031a0499a03fbe3546f3bb5ca05d01038c45b278c09a/scipy-1.18.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:f351e0dd702687d12a402b867a1b4146a256923e1c38317cbc472f6372b94707", size = 31399325, upload-time = "2026-06-19T15:01:13.723Z" }, + { url = "https://files.pythonhosted.org/packages/7b/d1/1f287b57c0ff0ee5185dff3946d92c8017d39b0e431f0ae79a3ff1859512/scipy-1.18.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7c7a51b33ce387193c97f228320cf8e87361daa1bba750638677729598b3e677", size = 29092110, upload-time = "2026-06-19T15:01:16.908Z" }, + { url = "https://files.pythonhosted.org/packages/ff/1a/7b74eb6c392fdcb27d414c0e7558a6d0231eb3b6d73571f479bb81ea8794/scipy-1.18.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:84031d7b052a54fae2f8632e0ec802073d385476eb9a63079bce6e23ef9283d4", size = 20833811, upload-time = "2026-06-19T15:01:20.488Z" }, + { url = "https://files.pythonhosted.org/packages/7c/ad/f3941716320a7b9cb4d68734a903b45fe16eff5fb7da7e16f2e619304979/scipy-1.18.0-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:56abf29a7c067dde59be8b9a22d606a4ea1b2f2a4b756d9d903c62818f5dacce", size = 23396644, upload-time = "2026-06-19T15:01:23.364Z" }, + { url = "https://files.pythonhosted.org/packages/22/22/1446b62ffe07f9719b7d9b1b6a4e05a772833ae8f441fe4c22c34c9b250f/scipy-1.18.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ad44305cfa24b1ba5803cbbebf033590ccbac1aa5d612d727b785325ab408b0", size = 34079318, upload-time = "2026-06-19T15:01:26.002Z" }, + { url = "https://files.pythonhosted.org/packages/56/3b/b87da667098bb470fa30c7011b0ba351ee976dd395c78798c66e941665a3/scipy-1.18.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:945c1761b93f38d7f99ae81ae80c63e621471608c7eeead563f6df025585cd58", size = 35324320, upload-time = "2026-06-19T15:01:28.881Z" }, + { url = "https://files.pythonhosted.org/packages/f8/a1/c7932f91909759b0267f75fdea34e91309f96b895757534b76a90b6b4344/scipy-1.18.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1a4441f15d620578772a49e5ab48c0ee1f7a0220e387110283062729136b2553", size = 35699541, upload-time = "2026-06-19T15:01:31.968Z" }, + { url = "https://files.pythonhosted.org/packages/f7/86/5185061a1fcc41d18c5dc2463969b3a3964b31d9ac67b2fb05d4c7ff7670/scipy-1.18.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9aac6192fac56bf2ca534389d24623f07b39ff83317d58287285e7fbd622ff76", size = 37472480, upload-time = "2026-06-19T15:01:35.136Z" }, + { url = "https://files.pythonhosted.org/packages/31/8e/f04c68e39919a010d34f2ee1367fd705b0a25a02f609d755f0bfbc0a15fc/scipy-1.18.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e40baea28ae7f5475c779741e2d90b1247c78531207b49c7030e698ff81cee3f", size = 37365390, upload-time = "2026-06-19T15:01:38.091Z" }, + { url = "https://files.pythonhosted.org/packages/d5/19/969dc072906c84dd0a3b05dcf57ea750936087d7873549e408b35cfc3f97/scipy-1.18.0-cp314-cp314t-win_arm64.whl", hash = "sha256:368e0a705903c466aa5f08eefb39e6b1b6b2d659e7352a31fd9e2438365be0f8", size = 25279661, upload-time = "2026-06-19T15:01:40.817Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "snowballstemmer" +version = "3.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/f8/0a71edf031f03c40db17503cb8ca78a69a171254e568e7db241b0ab57ea1/snowballstemmer-3.1.1.tar.gz", hash = "sha256:e07bbc54a0d798fe6010a12398422e62a8bfbba95c394fd0956ef58cb4d3e260", size = 123314, upload-time = "2026-06-03T00:56:40.194Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4c/07/2ebca9b11fb9be7340a818d8d6f63feaebb146be2c4afbd6061701d6df6e/snowballstemmer-3.1.1-py3-none-any.whl", hash = "sha256:7e207fa178741da09cdee59d3ecec3827ad5f92b1fc5c9ff3755b639f71f5752", size = 104164, upload-time = "2026-06-03T00:56:38.614Z" }, +] + +[[package]] +name = "sympy" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mpmath" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, +] + +[[package]] +name = "tomlkit" +version = "0.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/db/03eaf4331631ef6b27d6e3c9b68c54dc6f0d63d87201fed600cc409307fd/tomlkit-0.15.0.tar.gz", hash = "sha256:7d1a9ecba3086638211b13814ea79c90dd54dd11993564376f3aa92271f5c7a3", size = 161875, upload-time = "2026-05-10T07:38:22.245Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/43/8bd850ee71a191bf072e31302c73a66be413fecdd98fdcd111ecbcce13ca/tomlkit-0.15.0-py3-none-any.whl", hash = "sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738", size = 41328, upload-time = "2026-05-10T07:38:23.517Z" }, +]